-fix #3301
[oweals/gnunet.git] / src / namestore / namestore_api.c
index 8d3ea16ddbeef7db1093b0fafe29e4f94569169f..c089929a64c40652ce979d45063c275e2e6d7fdb 100644 (file)
@@ -33,6 +33,7 @@
 #include "gnunet_dnsparser_lib.h"
 #include "gnunet_arm_service.h"
 #include "gnunet_signatures.h"
+#include "gnunet_gns_service.h"
 #include "gnunet_namestore_service.h"
 #include "namestore.h"
 
@@ -265,8 +266,9 @@ handle_record_store_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
   const char *emsg;
 
   LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Received `%s'\n",
-       "RECORD_STORE_RESPONSE");
+       "Received `%s' with result %i\n",
+       "RECORD_STORE_RESPONSE",
+       ntohl (msg->op_result));
   /* TODO: add actual error message from namestore to response... */
   res = ntohl (msg->op_result);
   if (GNUNET_SYSERR == res)
@@ -279,6 +281,84 @@ handle_record_store_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
 }
 
 
+/**
+ * Handle an incoming message of type
+ * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP_RESPONSE
+ *
+ * @param qe the respective entry in the message queue
+ * @param msg the message we received
+ * @param size the message size
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR on error and we did NOT notify the client
+ */
+static int
+handle_lookup_result (struct GNUNET_NAMESTORE_QueueEntry *qe,
+                      const struct LabelLookupResponseMessage *msg,
+                      size_t size)
+{
+  const char *name;
+  const char *rd_tmp;
+  size_t exp_msg_len;
+  size_t msg_len;
+  size_t name_len;
+  size_t rd_len;
+  unsigned int rd_count;
+  int found;
+
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Received `%s'\n",
+       "RECORD_LOOKUP_RESULT");
+
+  rd_len = ntohs (msg->rd_len);
+  rd_count = ntohs (msg->rd_count);
+  msg_len = ntohs (msg->gns_header.header.size);
+  name_len = ntohs (msg->name_len);
+  found = ntohs (msg->found);
+  exp_msg_len = sizeof (struct LabelLookupResponseMessage) + name_len + rd_len;
+  if (msg_len != exp_msg_len)
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  name = (const char *) &msg[1];
+  if ( (name_len > 0) &&
+       ('\0' != name[name_len -1]) )
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  if (GNUNET_NO == found)
+  {
+    /* label was not in namestore */
+    if (NULL != qe->proc)
+      qe->proc (qe->proc_cls,
+                &msg->private_key,
+                name,
+                0, NULL);
+    return GNUNET_OK;
+  }
+
+  rd_tmp = &name[name_len];
+  {
+    struct GNUNET_GNSRECORD_Data rd[rd_count];
+
+    if (GNUNET_OK != GNUNET_GNSRECORD_records_deserialize(rd_len, rd_tmp, rd_count, rd))
+    {
+      GNUNET_break (0);
+      return GNUNET_SYSERR;
+    }
+    if (0 == name_len)
+      name = NULL;
+    if (NULL != qe->proc)
+      qe->proc (qe->proc_cls,
+                &msg->private_key,
+                name,
+                rd_count,
+                (rd_count > 0) ? rd : NULL);
+  }
+  return GNUNET_OK;
+}
+
+
 /**
  * Handle an incoming message of type
  * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT
@@ -379,7 +459,9 @@ handle_zone_to_name_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
   case GNUNET_NO:
     LOG (GNUNET_ERROR_TYPE_DEBUG,
         "Namestore has no result for zone to name mapping \n");
-    break;
+    if (NULL != qe->proc)
+      qe->proc (qe->proc_cls, &msg->zone, NULL, 0, NULL);
+    return GNUNET_NO;
   case GNUNET_YES:
     LOG (GNUNET_ERROR_TYPE_DEBUG,
         "Namestore has result for zone to name mapping \n");
@@ -462,6 +544,13 @@ manage_record_operations (struct GNUNET_NAMESTORE_QueueEntry *qe,
       return GNUNET_SYSERR;
     }
     return handle_record_result (qe, (const struct RecordResultMessage *) msg, size);
+  case GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP_RESPONSE:
+    if (size < sizeof (struct LabelLookupResponseMessage))
+    {
+      GNUNET_break (0);
+      return GNUNET_SYSERR;
+    }
+    return handle_lookup_result (qe, (const struct LabelLookupResponseMessage *) msg, size);
   default:
     GNUNET_break (0);
     return GNUNET_SYSERR;
@@ -910,7 +999,7 @@ GNUNET_NAMESTORE_disconnect (struct GNUNET_NAMESTORE_Handle *h)
  * @param rd_count number of records in the 'rd' array
  * @param rd array of records with data to store
  * @param cont continuation to call when done
- * @param cont_cls closure for 'cont'
+ * @param cont_cls closure for @a cont
  * @return handle to abort the request
  */
 struct GNUNET_NAMESTORE_QueueEntry *
@@ -980,6 +1069,34 @@ GNUNET_NAMESTORE_records_store (struct GNUNET_NAMESTORE_Handle *h,
   return qe;
 }
 
+/**
+ * Set the desired nick name for a zone
+ *
+ * @param h handle to the namestore
+ * @param pkey private key of the zone
+ * @param nick the nick name to set
+ * @param cont continuation to call when done
+ * @param cont_cls closure for 'cont'
+ * @return handle to abort the request
+ */
+struct GNUNET_NAMESTORE_QueueEntry *
+GNUNET_NAMESTORE_set_nick (struct GNUNET_NAMESTORE_Handle *h,
+                           const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
+                           const char *nick,
+                           GNUNET_NAMESTORE_ContinuationWithStatus cont,
+                           void *cont_cls)
+{
+  struct GNUNET_GNSRECORD_Data rd;
+
+  memset (&rd, 0, sizeof (rd));
+  rd.data = nick;
+  rd.data_size = strlen (nick) +1;
+  rd.record_type = GNUNET_GNSRECORD_TYPE_NICK;
+  rd.expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
+  rd.flags |= GNUNET_GNSRECORD_RF_PRIVATE;
+  return GNUNET_NAMESTORE_records_store(h, pkey, GNUNET_GNS_MASTERZONE_STR, 1, &rd, cont, cont_cls);
+}
+
 
 /**
  * Lookup an item in the namestore.
@@ -1022,11 +1139,12 @@ GNUNET_NAMESTORE_records_lookup (struct GNUNET_NAMESTORE_Handle *h,
   pe = GNUNET_malloc (sizeof (struct PendingMessage) + msg_size);
   pe->size = msg_size;
   msg = (struct LabelLookupMessage *) &pe[1];
-  msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_LABEL_LOOKUP);
+  msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP);
   msg->gns_header.header.size = htons (msg_size);
   msg->gns_header.r_id = htonl (qe->op_id);
   msg->zone = *pkey;
-  msg->label_len = htons(label_len);
+  msg->label_len = htonl(label_len);
+  memcpy (&msg[1], label, label_len);
 
   /* transmit message */
   GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);