-skeletons for transport-ng
[oweals/gnunet.git] / src / peerstore / peerstore_common.c
index 5783973b6e52a5d24e1fac4a6f5b749a4948d863..5a008ca62847f131e0d29fe6ee029315dc9cc293 100644 (file)
@@ -1,6 +1,6 @@
 /*
       This file is part of GNUnet
-      (C) 2012-2013 Christian Grothoff (and other contributing authors)
+      Copyright (C) 2012-2013 GNUnet e.V.
 
       GNUnet is free software; you can redistribute it and/or modify
       it under the terms of the GNU General Public License as published
@@ -14,8 +14,8 @@
 
       You should have received a copy of the GNU General Public License
       along with GNUnet; see the file COPYING.  If not, write to the
-      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-      Boston, MA 02111-1307, USA.
+      Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+      Boston, MA 02110-1301, USA.
  */
 /**
  * @file peerstore/peerstore_common.c
 
 #include "peerstore_common.h"
 
+/**
+ * Creates a hash of the given key combination
+ *
+ */
+void
+PEERSTORE_hash_key (const char *sub_system,
+                    const struct GNUNET_PeerIdentity *peer, const char *key,
+                    struct GNUNET_HashCode *ret)
+{
+  size_t sssize;
+  size_t psize;
+  size_t ksize;
+  size_t totalsize;
+  void *block;
+  void *blockptr;
+
+  sssize = strlen (sub_system) + 1;
+  psize = sizeof (struct GNUNET_PeerIdentity);
+  ksize = strlen (key) + 1;
+  totalsize = sssize + psize + ksize;
+  block = GNUNET_malloc (totalsize);
+  blockptr = block;
+  memcpy (blockptr, sub_system, sssize);
+  blockptr += sssize;
+  memcpy (blockptr, peer, psize);
+  blockptr += psize;
+  memcpy (blockptr, key, ksize);
+  GNUNET_CRYPTO_hash (block, totalsize, ret);
+  GNUNET_free (block);
+}
+
+
 /**
  * Creates a record message ready to be sent
  *
  * @return pointer to record message struct
  */
 struct StoreRecordMessage *
-PEERSTORE_create_record_message(const char *sub_system,
-    const struct GNUNET_PeerIdentity *peer,
-    const char *key,
-    const void *value,
-    size_t value_size,
-    struct GNUNET_TIME_Absolute *expiry,
-    uint16_t msg_type)
+PEERSTORE_create_record_message (const char *sub_system,
+                                 const struct GNUNET_PeerIdentity *peer,
+                                 const char *key, const void *value,
+                                 size_t value_size,
+                                 struct GNUNET_TIME_Absolute *expiry,
+                                 uint16_t msg_type)
 {
   struct StoreRecordMessage *srm;
   size_t ss_size;
@@ -52,40 +83,38 @@ PEERSTORE_create_record_message(const char *sub_system,
   size_t request_size;
   void *dummy;
 
-  ss_size = strlen(sub_system) + 1;
-  if(NULL == key)
+  ss_size = strlen (sub_system) + 1;
+  if (NULL == key)
     key_size = 0;
   else
-    key_size = strlen(key) + 1;
-  request_size = sizeof(struct StoreRecordMessage) +
-      ss_size +
-      key_size +
-      value_size;
-  srm = GNUNET_malloc(request_size);
-  srm->header.size = htons(request_size);
-  srm->header.type = htons(msg_type);
-  srm->key_size = htons(key_size);
-  if(NULL != expiry)
+    key_size = strlen (key) + 1;
+  request_size =
+      sizeof (struct StoreRecordMessage) + ss_size + key_size + value_size;
+  srm = GNUNET_malloc (request_size);
+  srm->header.size = htons (request_size);
+  srm->header.type = htons (msg_type);
+  srm->key_size = htons (key_size);
+  if (NULL != expiry)
     srm->expiry = *expiry;
-  if(NULL == peer)
-    srm->peer_set = htons(GNUNET_NO);
+  if (NULL == peer)
+    srm->peer_set = htons (GNUNET_NO);
   else
   {
-    srm->peer_set = htons(GNUNET_YES);
+    srm->peer_set = htons (GNUNET_YES);
     srm->peer = *peer;
   }
-  srm->sub_system_size = htons(ss_size);
-  srm->value_size = htons(value_size);
+  srm->sub_system_size = htons (ss_size);
+  srm->value_size = htons (value_size);
   dummy = &srm[1];
-  memcpy(dummy, sub_system, ss_size);
+  memcpy (dummy, sub_system, ss_size);
   dummy += ss_size;
-  memcpy(dummy, key, key_size);
+  memcpy (dummy, key, key_size);
   dummy += key_size;
-  memcpy(dummy, value, value_size);
+  memcpy (dummy, value, value_size);
   return srm;
-
 }
 
+
 /**
  * Creates a MQ envelope for a single record
  *
@@ -95,17 +124,18 @@ PEERSTORE_create_record_message(const char *sub_system,
  * @param value record value BLOB (can be NULL)
  * @param value_size record value size in bytes (set to 0 if value is NULL)
  * @param expiry time after which the record expires
+ * @param options options specific to the storage operation
  * @param msg_type message type to be set in header
  * @return pointer to record message struct
  */
 struct GNUNET_MQ_Envelope *
-PEERSTORE_create_record_mq_envelope(const char *sub_system,
-    const struct GNUNET_PeerIdentity *peer,
-    const char *key,
-    const void *value,
-    size_t value_size,
-    struct GNUNET_TIME_Absolute *expiry,
-    uint16_t msg_type)
+PEERSTORE_create_record_mq_envelope (const char *sub_system,
+                                     const struct GNUNET_PeerIdentity *peer,
+                                     const char *key, const void *value,
+                                     size_t value_size,
+                                     struct GNUNET_TIME_Absolute *expiry,
+                                     enum GNUNET_PEERSTORE_StoreOption options,
+                                     uint16_t msg_type)
 {
   struct StoreRecordMessage *srm;
   struct GNUNET_MQ_Envelope *ev;
@@ -114,38 +144,37 @@ PEERSTORE_create_record_mq_envelope(const char *sub_system,
   size_t msg_size;
   void *dummy;
 
-  GNUNET_assert(NULL != sub_system);
-  ss_size = strlen(sub_system) + 1;
-  if(NULL == key)
+  GNUNET_assert (NULL != sub_system);
+  ss_size = strlen (sub_system) + 1;
+  if (NULL == key)
     key_size = 0;
   else
-    key_size = strlen(key) + 1;
-  msg_size = ss_size +
-      key_size +
-      value_size;
-  ev = GNUNET_MQ_msg_extra(srm, msg_size, msg_type);
-  srm->key_size = htons(key_size);
-  if(NULL != expiry)
+    key_size = strlen (key) + 1;
+  msg_size = ss_size + key_size + value_size;
+  ev = GNUNET_MQ_msg_extra (srm, msg_size, msg_type);
+  srm->key_size = htons (key_size);
+  if (NULL != expiry)
     srm->expiry = *expiry;
-  if(NULL == peer)
-    srm->peer_set = htons(GNUNET_NO);
+  if (NULL == peer)
+    srm->peer_set = htons (GNUNET_NO);
   else
   {
-    srm->peer_set = htons(GNUNET_YES);
+    srm->peer_set = htons (GNUNET_YES);
     srm->peer = *peer;
   }
-  srm->sub_system_size = htons(ss_size);
-  srm->value_size = htons(value_size);
+  srm->sub_system_size = htons (ss_size);
+  srm->value_size = htons (value_size);
+  srm->options = htonl (options);
   dummy = &srm[1];
-  memcpy(dummy, sub_system, ss_size);
+  memcpy (dummy, sub_system, ss_size);
   dummy += ss_size;
-  memcpy(dummy, key, key_size);
+  memcpy (dummy, key, key_size);
   dummy += key_size;
-  memcpy(dummy, value, value_size);
-
+  memcpy (dummy, value, value_size);
   return ev;
 }
 
+
 /**
  * Parses a message carrying a record
  *
@@ -153,7 +182,7 @@ PEERSTORE_create_record_mq_envelope(const char *sub_system,
  * @return Pointer to record or NULL if error
  */
 struct GNUNET_PEERSTORE_Record *
-PEERSTORE_parse_record_message(const struct GNUNET_MessageHeader *message)
+PEERSTORE_parse_record_message (const struct GNUNET_MessageHeader *message)
 {
   struct StoreRecordMessage *srm;
   struct GNUNET_PEERSTORE_Record *record;
@@ -163,41 +192,82 @@ PEERSTORE_parse_record_message(const struct GNUNET_MessageHeader *message)
   uint16_t value_size;
   char *dummy;
 
-  req_size = ntohs(message->size);
-  if(req_size < sizeof(struct StoreRecordMessage))
+  req_size = ntohs (message->size);
+  if (req_size < sizeof (struct StoreRecordMessage))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                "Received message with invalid size: (%d < %d).\n",
+                (int) req_size,
+                (int) sizeof (struct StoreRecordMessage));
     return NULL;
-  srm = (struct StoreRecordMessage *)message;
-  ss_size = ntohs(srm->sub_system_size);
-  key_size = ntohs(srm->key_size);
-  value_size = ntohs(srm->value_size);
-  if(ss_size + key_size + value_size + sizeof(struct StoreRecordMessage)
-        != req_size)
+  }
+  srm = (struct StoreRecordMessage *) message;
+  ss_size = ntohs (srm->sub_system_size);
+  key_size = ntohs (srm->key_size);
+  value_size = ntohs (srm->value_size);
+  if (ss_size + key_size + value_size + sizeof (struct StoreRecordMessage) !=
+      req_size)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                "Received message with invalid sizes: (%d + %d + %d + %d != %d).\n",
+                ss_size,
+                key_size,
+                value_size,
+                (int) sizeof (struct StoreRecordMessage),
+                req_size);
     return NULL;
-  record = GNUNET_new(struct GNUNET_PEERSTORE_Record);
-  if(GNUNET_YES == ntohs(srm->peer_set))
+  }
+  record = GNUNET_new (struct GNUNET_PEERSTORE_Record);
+  if (GNUNET_YES == ntohs (srm->peer_set))
   {
-    record->peer = GNUNET_new(struct GNUNET_PeerIdentity);
-    memcpy(record->peer, &srm->peer, sizeof(struct GNUNET_PeerIdentity));
+    record->peer = GNUNET_new (struct GNUNET_PeerIdentity);
+
+    memcpy (record->peer, &srm->peer, sizeof (struct GNUNET_PeerIdentity));
   }
-  record->expiry = GNUNET_new(struct GNUNET_TIME_Absolute);
+  record->expiry = GNUNET_new (struct GNUNET_TIME_Absolute);
+
   *(record->expiry) = srm->expiry;
-  dummy = (char *)&srm[1];
-  if(ss_size > 0)
+  dummy = (char *) &srm[1];
+  if (ss_size > 0)
   {
-    record->sub_system = GNUNET_strdup(dummy);
+    record->sub_system = GNUNET_strdup (dummy);
     dummy += ss_size;
   }
-  if(key_size > 0)
+  if (key_size > 0)
   {
-    record->key = GNUNET_strdup(dummy);
+    record->key = GNUNET_strdup (dummy);
     dummy += key_size;
   }
-  if(value_size > 0)
+  if (value_size > 0)
   {
-    record->value = GNUNET_malloc(value_size);
-    memcpy(record->value, dummy, value_size);
+    record->value = GNUNET_malloc (value_size);
+    memcpy (record->value, dummy, value_size);
   }
   record->value_size = value_size;
-
   return record;
 }
+
+
+/**
+ * Free any memory allocated for this record
+ *
+ * @param record
+ */
+void
+PEERSTORE_destroy_record (struct GNUNET_PEERSTORE_Record *record)
+{
+  if (NULL != record->sub_system)
+    GNUNET_free (record->sub_system);
+  if (NULL != record->peer)
+    GNUNET_free (record->peer);
+  if (NULL != record->key)
+    GNUNET_free (record->key);
+  if (NULL != record->value)
+  {
+    GNUNET_free (record->value);
+    record->value = 0;
+  }
+  if (NULL != record->expiry)
+    GNUNET_free (record->expiry);
+  GNUNET_free (record);
+}