- put record
authorMatthias Wachs <wachs@net.in.tum.de>
Mon, 27 Feb 2012 14:26:17 +0000 (14:26 +0000)
committerMatthias Wachs <wachs@net.in.tum.de>
Mon, 27 Feb 2012 14:26:17 +0000 (14:26 +0000)
src/namestore/Makefile.am
src/namestore/gnunet-service-namestore.c
src/namestore/namestore.h
src/namestore/namestore_api.c
src/namestore/plugin_namestore_sqlite.c
src/namestore/test_namestore_api.c
src/namestore/test_namestore_api.conf

index 6f19d96d323eb99ff77ecfff8816f0a02b51232c..f3211d6a01db71c840ec1ca9bf0d0428dc145f1f 100644 (file)
@@ -76,7 +76,8 @@ test_namestore_api_LDADD = \
 
 EXTRADIST = \
   test_namestore_api.conf \
-  test_plugin_namestore_sqlite.conf
+  test_plugin_namestore_sqlite.conf \
+  hostkey
 
 
 test_plugin_namestore_sqlite_SOURCES = \
index e7c03bf213a3f1232a56cfdb5fc81747cfd9544c..1700925defd92197110d98a7e4d0fcdc734babc2 100644 (file)
@@ -287,7 +287,6 @@ handle_lookup_name_it (void *cls,
 
   if (GNUNET_YES == contains_signature)
     memcpy (signature_tmp, signature, sizeof (struct GNUNET_CRYPTO_RsaSignature));
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "DONE `%s' message\n", "NAMESTORE_LOOKUP_NAME_RESPONSE");
   GNUNET_SERVER_notification_context_unicast (snc, lnc->nc->client, (const struct GNUNET_MessageHeader *) lnr_msg, GNUNET_NO);
 
   GNUNET_free (lnr_msg);
@@ -349,6 +348,94 @@ static void handle_lookup_name (void *cls,
   GNUNET_SERVER_receive_done (client, GNUNET_OK);
 }
 
+static void handle_record_put (void *cls,
+                          struct GNUNET_SERVER_Client * client,
+                          const struct GNUNET_MessageHeader * message)
+{
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "NAMESTORE_RECORD_PUT");
+  struct GNUNET_NAMESTORE_Client *nc;
+  struct GNUNET_TIME_Absolute expire;
+  struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key;
+  struct GNUNET_NAMESTORE_RecordData *rd;
+  struct GNUNET_CRYPTO_RsaSignature *signature;
+  struct RecordPutResponseMessage rpr_msg;
+  size_t name_len;
+  size_t msg_size;
+  size_t msg_size_exp;
+  char * name;
+  uint32_t id = 0;
+  uint32_t rd_count;
+  int res = GNUNET_SYSERR;
+
+  if (ntohs (message->size) < sizeof (struct RecordPutMessage))
+  {
+    GNUNET_break_op (0);
+    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    return;
+  }
+
+  nc = client_lookup(client);
+  if (nc == NULL)
+  {
+    GNUNET_break_op (0);
+    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    return;
+  }
+
+  struct RecordPutMessage * rp_msg = (struct RecordPutMessage *) message;
+  id = ntohl (rp_msg->op_id);
+  name_len = ntohs (rp_msg->name_len);
+  rd_count = ntohl(rp_msg->rd_count);
+  msg_size = ntohs (message->size);
+  msg_size_exp = sizeof (struct RecordPutMessage) + sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) + name_len  + rd_count * (sizeof (struct GNUNET_NAMESTORE_RecordData));
+
+  if (msg_size != msg_size_exp)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Expected message %u size but message size is %u \n", msg_size_exp, msg_size);
+    GNUNET_break_op (0);
+    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    return;
+  }
+
+
+  if ((name_len == 0) || (name_len > 256))
+  {
+    GNUNET_break_op (0);
+    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    return;
+  }
+
+  zone_key = (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *) &rp_msg[1];
+  name = (char *) &zone_key[1];
+  expire = GNUNET_TIME_absolute_ntoh(rp_msg->expire);
+  signature = (struct GNUNET_CRYPTO_RsaSignature *) &rp_msg->signature;
+  rd = (struct GNUNET_NAMESTORE_RecordData *) &name[name_len];
+
+  /* Database operation */
+  res = GSN_database->put_records(GSN_database->cls,
+                                zone_key,
+                                expire,
+                                name,
+                                rd_count, rd,
+                                signature);
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Putting record for name `%s': %s\n",
+      name, (res == GNUNET_OK) ? "OK" : "FAIL");
+
+  /* Send response */
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message\n", "RECORD_PUT_RESPONSE");
+  rpr_msg.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT_RESPONSE);
+  rpr_msg.op_id = rp_msg->op_id;
+  rpr_msg.header.size = htons (sizeof (struct RecordPutResponseMessage));
+  if (GNUNET_OK == res)
+    rpr_msg.op_result = htons (GNUNET_OK);
+  else
+    rpr_msg.op_result = htons (GNUNET_NO);
+  GNUNET_SERVER_notification_context_unicast (snc, nc->client, (const struct GNUNET_MessageHeader *) &rpr_msg, GNUNET_NO);
+
+  GNUNET_SERVER_receive_done (client, GNUNET_OK);
+}
 
 /**
  * Process template requests.
@@ -370,6 +457,8 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
      GNUNET_MESSAGE_TYPE_NAMESTORE_START, sizeof (struct StartMessage)},
     {&handle_lookup_name, NULL,
      GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME, 0},
+     {&handle_record_put, NULL,
+      GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT, 0},
     {NULL, NULL, 0, 0}
   };
 
index 143f233d4623885ebee9c355fece48ba87a20038..03b4bb45a75f46c1be97b49071ba4446ab03bde6 100644 (file)
@@ -31,6 +31,8 @@
  */
 #define GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME 431
 #define GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPONSE 432
+#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT 433
+#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT_RESPONSE 434
 
 GNUNET_NETWORK_STRUCT_BEGIN
 /**
@@ -67,11 +69,10 @@ struct GenericMessage
 GNUNET_NETWORK_STRUCT_END
 
 
-
-GNUNET_NETWORK_STRUCT_BEGIN
 /**
  * Connect to namestore service
  */
+GNUNET_NETWORK_STRUCT_BEGIN
 struct LookupNameMessage
 {
   /**
@@ -96,15 +97,12 @@ struct LookupNameMessage
 GNUNET_NETWORK_STRUCT_END
 
 
-
-GNUNET_NETWORK_STRUCT_BEGIN
-
 /**
  * Lookup response
  * Memory layout:
  * [struct LookupNameResponseMessage][struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded][char *name][rc_count * struct GNUNET_NAMESTORE_RecordData][struct GNUNET_CRYPTO_RsaSignature]
  */
-
+GNUNET_NETWORK_STRUCT_BEGIN
 struct LookupNameResponseMessage
 {
   /**
@@ -126,10 +124,69 @@ struct LookupNameResponseMessage
   /* Requested record type */
   uint32_t rc_count;
 };
+GNUNET_NETWORK_STRUCT_END
+
+
+/**
+ * Put a record to the namestore
+ * Memory layout:
+ * [struct RecordPutMessage][struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded][char *name][rc_count * struct GNUNET_NAMESTORE_RecordData]
+ */
+GNUNET_NETWORK_STRUCT_BEGIN
+struct RecordPutMessage
+{
+  /**
+   * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_RECORD_PUT
+   */
+  struct GNUNET_MessageHeader header;
+
+  /**
+   * Operation ID in NBO
+   */
+  uint32_t op_id;
+
+  /* Contenct starts here */
+
+  /* name length */
+  uint16_t name_len;
+
+  /* Requested record type */
+  uint32_t rd_count;
+
+  struct GNUNET_TIME_AbsoluteNBO expire;
+
+  struct GNUNET_CRYPTO_RsaSignature signature;
+};
+GNUNET_NETWORK_STRUCT_END
+
+/**
+ * Put a record to the namestore
+ * Memory layout:
+ * [struct RecordPutMessage][struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded][char *name][rc_count * struct GNUNET_NAMESTORE_RecordData]
+ */
+GNUNET_NETWORK_STRUCT_BEGIN
+struct RecordPutResponseMessage
+{
+  /**
+   * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT_RESPONSE
+   */
+  struct GNUNET_MessageHeader header;
 
+  /**
+   * Operation ID in NBO
+   */
+  uint32_t op_id;
+
+  /* Contenct starts here */
 
+  /**
+   *  name length: GNUNET_NO (0) on error, GNUNET_OK (1) on success
+   */
+  uint16_t op_result;
+};
 GNUNET_NETWORK_STRUCT_END
 
 
+
 /* end of namestore.h */
 #endif
index 21b24567a95092d327258975e2d47b3c3373aba6..882e5a5de8f2937b9c039760a4f5f451abe18449 100644 (file)
@@ -245,12 +245,51 @@ handle_lookup_name_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
   {
     qe->proc (qe->proc_cls, zone_key, expire, name, rd_count, rd, signature);
   }
+  /* Operation done, remove */
+  GNUNET_CONTAINER_DLL_remove(h->op_head, h->op_tail, qe);
+  GNUNET_free (qe);
+}
+
+
+static void
+handle_record_put_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
+                             struct RecordPutResponseMessage* msg,
+                             size_t size)
+{
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' \n",
+              "RECORD_PUT_RESPONSE");
+
+  struct GNUNET_NAMESTORE_Handle *h = qe->nsh;
+  int res = GNUNET_OK;
+
+  if (ntohs (msg->op_result) == GNUNET_OK)
+  {
+    res = GNUNET_OK;
+    if (qe->cont != NULL)
+    {
+      qe->cont (qe->cont_cls, res, _("Namestore added record successfully"));
+    }
+
+  }
+  else if (ntohs (msg->op_result) == GNUNET_NO)
+  {
+    res = GNUNET_SYSERR;
+    if (qe->cont != NULL)
+    {
+      qe->cont (qe->cont_cls, res, _("Namestore failed to add record"));
+    }
+  }
+  else
+  {
+    GNUNET_break_op (0);
+    return;
+  }
 
 
   /* Operation done, remove */
   GNUNET_CONTAINER_DLL_remove(h->op_head, h->op_tail, qe);
-  GNUNET_free (qe);
 
+  GNUNET_free (qe);
 }
 
 
@@ -326,6 +365,14 @@ process_namestore_message (void *cls, const struct GNUNET_MessageHeader *msg)
         }
         handle_lookup_name_response (qe, (struct LookupNameResponseMessage *) msg, size);
       break;
+    case GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT_RESPONSE:
+        if (size != sizeof (struct RecordPutResponseMessage))
+        {
+          GNUNET_break_op (0);
+          break;
+        }
+        handle_record_put_response (qe, (struct RecordPutResponseMessage *) msg, size);
+      break;
     default:
       GNUNET_break_op (0);
       break;
@@ -575,7 +622,14 @@ GNUNET_NAMESTORE_record_put (struct GNUNET_NAMESTORE_Handle *h,
 {
   struct GNUNET_NAMESTORE_QueueEntry *qe;
   struct PendingMessage *pe;
+
+  /* pointer to elements */
+  struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key_tmp;
+  struct GNUNET_NAMESTORE_RecordData *rd_tmp;
+  char * name_tmp;
+
   size_t msg_size = 0;
+  size_t name_len = strlen(name) + 1;
   uint32_t id = 0;
 
   GNUNET_assert (NULL != h);
@@ -588,24 +642,40 @@ GNUNET_NAMESTORE_record_put (struct GNUNET_NAMESTORE_Handle *h,
   GNUNET_CONTAINER_DLL_insert(h->op_head, h->op_tail, qe);
 
   /* set msg_size*/
-  pe = GNUNET_malloc(sizeof (struct PendingMessage) + msg_size);
+  struct RecordPutMessage * msg;
+  msg_size = sizeof (struct RecordPutMessage) + sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) + name_len  + rd_count * (sizeof (struct GNUNET_NAMESTORE_RecordData));
 
   /* create msg here */
+  pe = GNUNET_malloc(sizeof (struct PendingMessage) + msg_size);
+  pe->size = msg_size;
+  pe->is_init = GNUNET_NO;
+  msg = (struct RecordPutMessage *) &pe[1];
+  zone_key_tmp = (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *) &msg[1];
+  name_tmp = (char *) &zone_key_tmp[1];
+  rd_tmp = (struct GNUNET_NAMESTORE_RecordData *) &name_tmp[name_len];
+
+  msg->header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT);
+  msg->header.size = htons (msg_size);
+  msg->op_id = htonl (id);
+  memcpy (zone_key_tmp, zone_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
+  msg->signature = *signature;
+  msg->name_len = htons (name_len);
+  memcpy (name_tmp, name, name_len);
+  msg->expire = GNUNET_TIME_absolute_hton (expire);
+  msg->rd_count = htonl(rd_count);
+  memcpy (rd_tmp, rd, rd_count * (sizeof (struct GNUNET_NAMESTORE_RecordData)));
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message for name `%s' with size %u\n", "NAMESTORE_RECORD_PUT", name, msg_size);
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CALC: %u %u %u %u\n",
+      sizeof (struct RecordPutMessage),
+      sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
+      name_len,
+      rd_count * (sizeof (struct GNUNET_NAMESTORE_RecordData)));
 
   GNUNET_CONTAINER_DLL_insert (h->pending_head, h->pending_tail, pe);
   do_transmit(h);
 
-#if 0
-  struct GNUNET_NAMESTORE_SimpleRecord *sr;
-  sr = GNUNET_malloc(sizeof(struct GNUNET_NAMESTORE_SimpleRecord));
-  sr->name = name;
-  sr->record_type = record_type;
-  sr->expiration = expiration;
-  sr->flags = flags;
-  sr->data_size = data_size;
-  sr->data = data;
-  GNUNET_CONTAINER_DLL_insert(h->records_head, h->records_tail, sr);
-#endif
   return qe;
 }
 
index ba8f8bca6585f41428603d32c63cc53283bafb72..c2972164302e602a1ab4584f003431cb1b20ff7c 100644 (file)
@@ -465,7 +465,7 @@ namestore_sqlite_remove_records (void *cls,
  * @param rd array of records with data to store
  * @param signature signature of the record block, NULL if signature is unavailable (i.e. 
  *        because the user queried for a particular record type only)
- * @return GNUNET_OK on success
+ * @return GNUNET_OK on success, else GNUNET_SYSERR
  */
 static int 
 namestore_sqlite_put_records (void *cls, 
index 62cfa808a30bd5ac03d51f7336ec13281eb967d0..b907c713920da80783933e352540529512de0298 100644 (file)
@@ -34,6 +34,10 @@ static struct GNUNET_NAMESTORE_Handle * nsh;
 static GNUNET_SCHEDULER_TaskIdentifier endbadly_task;
 static struct GNUNET_OS_Process *arm;
 
+static struct GNUNET_CRYPTO_RsaPrivateKey * privkey;
+static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey;
+static GNUNET_HashCode zone;
+
 static int res;
 
 
@@ -76,6 +80,10 @@ endbadly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
     GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES);
   nsh = NULL;
 
+  if (privkey != NULL)
+    GNUNET_CRYPTO_rsa_key_free (privkey);
+  privkey = NULL;
+
   if (NULL != arm)
     stop_arm();
 
@@ -92,6 +100,10 @@ end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
     endbadly_task = GNUNET_SCHEDULER_NO_TASK;
   }
 
+  if (privkey != NULL)
+    GNUNET_CRYPTO_rsa_key_free (privkey);
+  privkey = NULL;
+
   if (nsh != NULL)
     GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES);
   nsh = NULL;
@@ -112,19 +124,34 @@ void name_lookup_proc (void *cls,
                             const struct GNUNET_NAMESTORE_RecordData *rd,
                             const struct GNUNET_CRYPTO_RsaSignature *signature)
 {
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "name_lookup_proc %p `%s' %i %p %p\n", zone_key, name, rd_count, rd, signature);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Namestore lookup result %p `%s' %i %p %p\n", zone_key, name, rd_count, rd, signature);
   res = 0;
   GNUNET_SCHEDULER_add_now(&end, NULL);
 }
 
+void put_cont (void *cls, int32_t success, const char *emsg)
+{
+  char * name = cls;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name store added record for `%s': %s\n", name, (success == GNUNET_OK) ? "SUCCESS" : "FAIL");
+
+  GNUNET_NAMESTORE_lookup_record (nsh, &zone, name, 0, &name_lookup_proc, NULL);
+}
+
 static void
 run (void *cls, char *const *args, const char *cfgfile,
      const struct GNUNET_CONFIGURATION_Handle *cfg)
 {
   endbadly_task = GNUNET_SCHEDULER_add_delayed(TIMEOUT,endbadly, NULL);
 
-  GNUNET_HashCode zone;
-  GNUNET_CRYPTO_hash_create_random(GNUNET_CRYPTO_QUALITY_WEAK, &zone);
+  privkey = GNUNET_CRYPTO_rsa_key_create_from_file("hostkey");
+  GNUNET_assert (privkey != NULL);
+  GNUNET_CRYPTO_rsa_key_get_public(privkey, &pubkey);
+
+  GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, &zone);
+
+
+  struct GNUNET_CRYPTO_RsaSignature signature;
   char * name = "dummy.dummy.gnunet";
 
   start_arm (cfgfile);
@@ -133,7 +160,9 @@ run (void *cls, char *const *args, const char *cfgfile,
   nsh = GNUNET_NAMESTORE_connect (cfg);
   GNUNET_break (NULL != nsh);
 
-  GNUNET_NAMESTORE_lookup_record (nsh, &zone, name, 0, &name_lookup_proc, NULL);
+  GNUNET_NAMESTORE_record_put (nsh, &pubkey, name,
+                              GNUNET_TIME_absolute_get_forever(),
+                              0, NULL, &signature, put_cont, name);
 }
 
 static int
index 1683d13cf5154b99a86d59cf2ee4ba43b19d0007..1b83e8f13a84d6f9ccae6a8740b53f59713827dd 100644 (file)
@@ -4,7 +4,7 @@ DEFAULTSERVICES = namestore
 UNIXPATH = /tmp/gnunet-p1-service-arm.sock
 
 [namestore]
-PREFIX = valgrind --leak-check=full
+#PREFIX = valgrind --leak-check=full
 AUTOSTART = YES
 UNIXPATH = /tmp/gnunet-service-namestore.sock
 UNIX_MATCH_UID = YES