gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnunet] branch master updated: GNS: Rework GNS block wire format


From: gnunet
Subject: [gnunet] branch master updated: GNS: Rework GNS block wire format
Date: Thu, 03 Feb 2022 09:25:19 +0100

This is an automated email from the git hooks/post-receive script.

martin-schanzenbach pushed a commit to branch master
in repository gnunet.

The following commit(s) were added to refs/heads/master by this push:
     new 112ef3796 GNS: Rework GNS block wire format
112ef3796 is described below

commit 112ef3796314122465f23215233d8b7dd7a15a0b
Author: Martin Schanzenbach <schanzen@gnunet.org>
AuthorDate: Thu Feb 3 09:25:12 2022 +0100

    GNS: Rework GNS block wire format
---
 src/gnsrecord/gnsrecord_crypto.c        | 311 ++++++++++++++++++--------------
 src/gnsrecord/gnsrecord_crypto.h        |  20 ++
 src/gnsrecord/gnsrecord_misc.c          |  19 +-
 src/gnsrecord/gnsrecord_serialization.c |  56 +++++-
 src/gnsrecord/gnunet-gnsrecord-tvg.c    |  82 ++++-----
 src/gnsrecord/test_gnsrecord_crypto.c   |  12 +-
 src/include/gnunet_gnsrecord_lib.h      |  76 +++++---
 7 files changed, 337 insertions(+), 239 deletions(-)

diff --git a/src/gnsrecord/gnsrecord_crypto.c b/src/gnsrecord/gnsrecord_crypto.c
index 24f4c48ca..890ddb011 100644
--- a/src/gnsrecord/gnsrecord_crypto.c
+++ b/src/gnsrecord/gnsrecord_crypto.c
@@ -95,8 +95,8 @@ eddsa_symmetric_decrypt (
   if (ctlen < 0)
     return GNUNET_SYSERR;
   if (0 != crypto_secretbox_open_detached (result,
-                                           block, // Ciphertext
-                                           ((unsigned char*) block) + ctlen, 
// TAG
+                                           ((unsigned char*) block) + 
crypto_secretbox_MACBYTES, // Ciphertext
+                                           block, // Tag
                                            ctlen,
                                            nonce, key))
   {
@@ -116,8 +116,8 @@ eddsa_symmetric_encrypt (
 {
   if (size > crypto_secretbox_MESSAGEBYTES_MAX)
     return GNUNET_SYSERR;
-  crypto_secretbox_detached (result, // Ciphertext
-                             result + size, // TAG
+  crypto_secretbox_detached (result + crypto_secretbox_MACBYTES, // Ciphertext
+                             result, // TAG
                              block, size, nonce, key);
   return GNUNET_OK;
 }
@@ -180,6 +180,20 @@ GNR_derive_block_xsalsa_key (unsigned char *nonce,
 }
 
 
+static ssize_t
+block_get_size_ecdsa (const struct GNUNET_GNSRECORD_Data *rd,
+                      unsigned int rd_count)
+{
+  ssize_t len;
+
+  len = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
+  if (len < 0)
+    return -1;
+  len += sizeof(struct GNUNET_GNSRECORD_Block);
+  return len;
+}
+
+
 /**
  * Sign name and records
  *
@@ -189,20 +203,22 @@ GNR_derive_block_xsalsa_key (unsigned char *nonce,
  * @param label the name for the records
  * @param rd record data
  * @param rd_count number of records
- * @return NULL on error (block too large)
+ * @param block the block result. Must be allocated sufficiently.
+ * @return GNUNET_SYSERR on error (otherwise GNUNET_OK)
  */
-static struct GNUNET_GNSRECORD_Block *
+static enum GNUNET_GenericReturnValue
 block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
                     const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey,
                     struct GNUNET_TIME_Absolute expire,
                     const char *label,
                     const struct GNUNET_GNSRECORD_Data *rd,
-                    unsigned int rd_count)
+                    unsigned int rd_count,
+                    struct GNUNET_GNSRECORD_Block **block)
 {
   ssize_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count,
                                                            rd);
-  struct GNUNET_GNSRECORD_Block *block;
   struct GNUNET_GNSRECORD_EcdsaBlock *ecblock;
+  struct GNRBlockPS *gnr_block;
   struct GNUNET_CRYPTO_EcdsaPrivateKey *dkey;
   unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2];
   unsigned char skey[GNUNET_CRYPTO_AES_KEY_LENGTH];
@@ -213,12 +229,12 @@ block_create_ecdsa (const struct 
GNUNET_CRYPTO_EcdsaPrivateKey *key,
   if (payload_len < 0)
   {
     GNUNET_break (0);
-    return NULL;
+    return GNUNET_SYSERR;
   }
   if (payload_len > GNUNET_GNSRECORD_MAX_BLOCK_SIZE)
   {
     GNUNET_break (0);
-    return NULL;
+    return GNUNET_SYSERR;
   }
   /* convert relative to absolute times */
   now = GNUNET_TIME_absolute_get ();
@@ -236,31 +252,25 @@ block_create_ecdsa (const struct 
GNUNET_CRYPTO_EcdsaPrivateKey *key,
     }
   }
   /* serialize */
+  *block = GNUNET_malloc (sizeof (struct GNUNET_GNSRECORD_Block) + 
payload_len);
+  (*block)->size = htonl(sizeof (struct GNUNET_GNSRECORD_Block) + payload_len);
   rd_count_nbo = htonl (rd_count);
   {
-    char payload[sizeof(uint32_t) + payload_len];
+    char payload[payload_len];
 
-    GNUNET_memcpy (payload,
-                   &rd_count_nbo,
-                   sizeof(uint32_t));
     GNUNET_assert (payload_len ==
                    GNUNET_GNSRECORD_records_serialize (rd_count,
                                                        rdc,
                                                        payload_len,
-                                                       
&payload[sizeof(uint32_t)
-                                                       ]));
-    block = GNUNET_malloc (sizeof(struct GNUNET_GNSRECORD_Block)
-                           + sizeof(uint32_t)
-                           + payload_len);
-    ecblock = &block->ecdsa_block;
-    block->type = htonl (GNUNET_GNSRECORD_TYPE_PKEY);
-    ecblock->purpose.size = htonl (sizeof(uint32_t)
-                                   + payload_len
-                                   + sizeof(struct
-                                            GNUNET_CRYPTO_EccSignaturePurpose)
-                                   + sizeof(struct GNUNET_TIME_AbsoluteNBO));
-    ecblock->purpose.purpose = htonl 
(GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
-    ecblock->expiration_time = GNUNET_TIME_absolute_hton (expire);
+                                                       payload));
+    gnr_block = GNUNET_malloc (sizeof (struct GNRBlockPS) + payload_len);
+    ecblock = &(*block)->ecdsa_block;
+    (*block)->type = htonl (GNUNET_GNSRECORD_TYPE_PKEY);
+    gnr_block->purpose.size = htonl (sizeof(struct GNRBlockPS) + payload_len);
+    gnr_block->purpose.purpose =
+      htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
+    gnr_block->expiration_time = GNUNET_TIME_absolute_hton (expire);
+    ecblock->expiration_time = gnr_block->expiration_time;
     /* encrypt and sign */
     dkey = GNUNET_CRYPTO_ecdsa_private_key_derive (key,
                                                    label,
@@ -272,26 +282,40 @@ block_create_ecdsa (const struct 
GNUNET_CRYPTO_EcdsaPrivateKey *key,
                               label,
                               ecblock->expiration_time.abs_value_us__,
                               pkey);
-    GNUNET_break (payload_len + sizeof(uint32_t) ==
+    GNUNET_break (payload_len ==
                   ecdsa_symmetric_encrypt (payload,
-                                           payload_len
-                                           + sizeof(uint32_t),
+                                           payload_len,
                                            skey,
                                            ctr,
                                            &ecblock[1]));
+    GNUNET_memcpy (&gnr_block[1], &ecblock[1], payload_len);
   }
   if (GNUNET_OK !=
       GNUNET_CRYPTO_ecdsa_sign_ (dkey,
-                                 &ecblock->purpose,
+                                 &gnr_block->purpose,
                                  &ecblock->signature))
   {
     GNUNET_break (0);
+    GNUNET_free (*block);
     GNUNET_free (dkey);
-    GNUNET_free (block);
-    return NULL;
+    return GNUNET_SYSERR;
   }
   GNUNET_free (dkey);
-  return block;
+  return GNUNET_OK;
+}
+
+static ssize_t
+block_get_size_eddsa (const struct GNUNET_GNSRECORD_Data *rd,
+                      unsigned int rd_count)
+{
+  ssize_t len;
+
+  len = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
+  if (len < 0)
+    return -1;
+  len += sizeof(struct GNUNET_GNSRECORD_Block);
+  len += crypto_secretbox_MACBYTES;
+  return len;
 }
 
 
@@ -304,20 +328,22 @@ block_create_ecdsa (const struct 
GNUNET_CRYPTO_EcdsaPrivateKey *key,
  * @param label the name for the records
  * @param rd record data
  * @param rd_count number of records
- * @return NULL on error (block too large)
+ * @param block where to store the block. Must be allocated sufficiently.
+ * @return GNUNET_SYSERR on error (otherwise GNUNET_OK)
  */
-static struct GNUNET_GNSRECORD_Block *
+enum GNUNET_GenericReturnValue
 block_create_eddsa (const struct GNUNET_CRYPTO_EddsaPrivateKey *key,
                     const struct GNUNET_CRYPTO_EddsaPublicKey *pkey,
                     struct GNUNET_TIME_Absolute expire,
                     const char *label,
                     const struct GNUNET_GNSRECORD_Data *rd,
-                    unsigned int rd_count)
+                    unsigned int rd_count,
+                    struct GNUNET_GNSRECORD_Block **block)
 {
   ssize_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count,
                                                            rd);
-  struct GNUNET_GNSRECORD_Block *block;
   struct GNUNET_GNSRECORD_EddsaBlock *edblock;
+  struct GNRBlockPS *gnr_block;
   struct GNUNET_CRYPTO_EddsaPrivateScalar dkey;
   unsigned char nonce[crypto_secretbox_NONCEBYTES];
   unsigned char skey[crypto_secretbox_KEYBYTES];
@@ -328,12 +354,12 @@ block_create_eddsa (const struct 
GNUNET_CRYPTO_EddsaPrivateKey *key,
   if (payload_len < 0)
   {
     GNUNET_break (0);
-    return NULL;
+    return GNUNET_SYSERR;
   }
   if (payload_len > GNUNET_GNSRECORD_MAX_BLOCK_SIZE)
   {
     GNUNET_break (0);
-    return NULL;
+    return GNUNET_SYSERR;
   }
   /* convert relative to absolute times */
   now = GNUNET_TIME_absolute_get ();
@@ -351,33 +377,32 @@ block_create_eddsa (const struct 
GNUNET_CRYPTO_EddsaPrivateKey *key,
     }
   }
   /* serialize */
+  *block = GNUNET_malloc (sizeof (struct GNUNET_GNSRECORD_Block)
+                          + payload_len + crypto_secretbox_MACBYTES);
+  (*block)->size = htonl(sizeof (struct GNUNET_GNSRECORD_Block)
+                 + payload_len + crypto_secretbox_MACBYTES);
   rd_count_nbo = htonl (rd_count);
   {
-    char payload[sizeof(uint32_t) + payload_len];
+    char payload[payload_len];
 
-    GNUNET_memcpy (payload,
-                   &rd_count_nbo,
-                   sizeof(uint32_t));
     GNUNET_assert (payload_len ==
                    GNUNET_GNSRECORD_records_serialize (rd_count,
                                                        rdc,
                                                        payload_len,
-                                                       
&payload[sizeof(uint32_t)
-                                                       ]));
-    block = GNUNET_malloc (sizeof(struct GNUNET_GNSRECORD_Block)
-                           + sizeof(uint32_t)
-                           + payload_len
-                           + crypto_secretbox_MACBYTES);
-    edblock = &block->eddsa_block;
-    block->type = htonl (GNUNET_GNSRECORD_TYPE_EDKEY);
-    edblock->purpose.size = htonl (sizeof(uint32_t)
-                                   + payload_len
-                                   + sizeof(struct
-                                            GNUNET_CRYPTO_EccSignaturePurpose)
-                                   + sizeof(struct GNUNET_TIME_AbsoluteNBO)
-                                   + crypto_secretbox_MACBYTES);
-    edblock->purpose.purpose = htonl 
(GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
-    edblock->expiration_time = GNUNET_TIME_absolute_hton (expire);
+                                                       payload));
+    gnr_block = GNUNET_malloc (sizeof (struct GNRBlockPS)
+                               + payload_len
+                               + crypto_secretbox_MACBYTES);
+    edblock = &(*block)->eddsa_block;
+    (*block)->type = htonl (GNUNET_GNSRECORD_TYPE_EDKEY);
+    gnr_block->purpose.size =
+      htonl (sizeof(struct GNRBlockPS)
+             + payload_len
+             + crypto_secretbox_MACBYTES);
+    gnr_block->purpose.purpose =
+      htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
+    gnr_block->expiration_time = GNUNET_TIME_absolute_hton (expire);
+    edblock->expiration_time = gnr_block->expiration_time;
     /* encrypt and sign */
     GNUNET_CRYPTO_eddsa_private_key_derive (key,
                                             label,
@@ -392,38 +417,56 @@ block_create_eddsa (const struct 
GNUNET_CRYPTO_EddsaPrivateKey *key,
                                  pkey);
     GNUNET_break (GNUNET_OK ==
                   eddsa_symmetric_encrypt (payload,
-                                           payload_len
-                                           + sizeof(uint32_t),
+                                           payload_len,
                                            skey,
                                            nonce,
                                            &edblock[1]));
+    GNUNET_memcpy (&gnr_block[1], &edblock[1],
+                   payload_len + crypto_secretbox_MACBYTES);
+
+    GNUNET_CRYPTO_eddsa_sign_with_scalar (&dkey,
+                                          &gnr_block->purpose,
+                                          &edblock->signature);
   }
-  GNUNET_CRYPTO_eddsa_sign_with_scalar (&dkey,
-                                        &edblock->purpose,
-                                        &edblock->signature);
-  return block;
+  return GNUNET_OK;
 }
 
+ssize_t
+GNUNET_GNSRECORD_block_calculate_size (const struct
+                                       GNUNET_IDENTITY_PrivateKey *key,
+                                       const struct GNUNET_GNSRECORD_Data *rd,
+                                       unsigned int rd_count)
+{
+  struct GNUNET_IDENTITY_PublicKey pkey;
+  ssize_t res;
 
-/**
- * Sign name and records
- *
- * @param key the private key
- * @param expire block expiration
- * @param label the name for the records
- * @param rd record data
- * @param rd_count number of records
- * @return NULL on error (block too large)
- */
-struct GNUNET_GNSRECORD_Block *
+  GNUNET_IDENTITY_key_get_public (key,
+                                  &pkey);
+  switch (ntohl (key->type))
+  {
+  case GNUNET_GNSRECORD_TYPE_PKEY:
+    res = block_get_size_ecdsa (rd, rd_count);
+    break;
+  case GNUNET_GNSRECORD_TYPE_EDKEY:
+    res = block_get_size_eddsa (rd, rd_count);
+    break;
+  default:
+    GNUNET_assert (0);
+  }
+  return -1;
+
+}
+
+enum GNUNET_GenericReturnValue
 GNUNET_GNSRECORD_block_create (const struct GNUNET_IDENTITY_PrivateKey *key,
                                struct GNUNET_TIME_Absolute expire,
                                const char *label,
                                const struct GNUNET_GNSRECORD_Data *rd,
-                               unsigned int rd_count)
+                               unsigned int rd_count,
+                               struct GNUNET_GNSRECORD_Block **result)
 {
   struct GNUNET_IDENTITY_PublicKey pkey;
-  struct GNUNET_GNSRECORD_Block *res = NULL;
+  enum GNUNET_GenericReturnValue res = GNUNET_SYSERR;
   char *norm_label;
 
   GNUNET_IDENTITY_key_get_public (key,
@@ -438,7 +481,8 @@ GNUNET_GNSRECORD_block_create (const struct 
GNUNET_IDENTITY_PrivateKey *key,
                               expire,
                               norm_label,
                               rd,
-                              rd_count);
+                              rd_count,
+                              result);
     break;
   case GNUNET_GNSRECORD_TYPE_EDKEY:
     res = block_create_eddsa (&key->eddsa_key,
@@ -446,7 +490,8 @@ GNUNET_GNSRECORD_block_create (const struct 
GNUNET_IDENTITY_PrivateKey *key,
                               expire,
                               norm_label,
                               rd,
-                              rd_count);
+                              rd_count,
+                              result);
     break;
   default:
     GNUNET_assert (0);
@@ -473,28 +518,17 @@ struct KeyCacheLine
 };
 
 
-/**
- * Sign name and records, cache derived public key (also keeps the
- * private key in static memory, so do not use this function if
- * keeping the private key in the process'es RAM is a major issue).
- *
- * @param key the private key
- * @param expire block expiration
- * @param label the name for the records
- * @param rd record data
- * @param rd_count number of records
- * @return NULL on error (block too large)
- */
-struct GNUNET_GNSRECORD_Block *
+enum GNUNET_GenericReturnValue
 GNUNET_GNSRECORD_block_create2 (const struct GNUNET_IDENTITY_PrivateKey *pkey,
                                 struct GNUNET_TIME_Absolute expire,
                                 const char *label,
                                 const struct GNUNET_GNSRECORD_Data *rd,
-                                unsigned int rd_count)
+                                unsigned int rd_count,
+                                struct GNUNET_GNSRECORD_Block **result)
 {
   const struct GNUNET_CRYPTO_EcdsaPrivateKey *key;
   struct GNUNET_CRYPTO_EddsaPublicKey edpubkey;
-  struct GNUNET_GNSRECORD_Block *res = NULL;
+  enum GNUNET_GenericReturnValue res = GNUNET_SYSERR;
   char *norm_label;
 
   norm_label = GNUNET_GNSRECORD_string_normalize (label);
@@ -522,7 +556,8 @@ GNUNET_GNSRECORD_block_create2 (const struct 
GNUNET_IDENTITY_PrivateKey *pkey,
                               expire,
                               norm_label,
                               rd,
-                              rd_count);
+                              rd_count,
+                              result);
   }
   else if (GNUNET_IDENTITY_TYPE_EDDSA == ntohl (pkey->type))
   {
@@ -533,7 +568,8 @@ GNUNET_GNSRECORD_block_create2 (const struct 
GNUNET_IDENTITY_PrivateKey *pkey,
                               expire,
                               norm_label,
                               rd,
-                              rd_count);
+                              rd_count,
+                              result);
   }
   GNUNET_free (norm_label);
   return res;
@@ -550,41 +586,55 @@ GNUNET_GNSRECORD_block_create2 (const struct 
GNUNET_IDENTITY_PrivateKey *pkey,
 enum GNUNET_GenericReturnValue
 GNUNET_GNSRECORD_block_verify (const struct GNUNET_GNSRECORD_Block *block)
 {
+  struct GNRBlockPS *purp;
+  size_t payload_len = ntohl (block->size)
+                       - sizeof (struct GNUNET_GNSRECORD_Block);
+  enum GNUNET_GenericReturnValue res = GNUNET_NO;
+  purp = GNUNET_malloc (sizeof (struct GNRBlockPS) + payload_len);
+  purp->purpose.size = htonl (sizeof (struct GNRBlockPS) + payload_len);
+  purp->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
+  GNUNET_memcpy (&purp[1], &block[1], payload_len);
+
   switch (ntohl (block->type))
   {
   case GNUNET_GNSRECORD_TYPE_PKEY:
-    return GNUNET_CRYPTO_ecdsa_verify_ (
+    purp->expiration_time = block->ecdsa_block.expiration_time;
+    res = GNUNET_CRYPTO_ecdsa_verify_ (
       GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN,
-      &block->ecdsa_block.purpose,
+      &purp->purpose,
       &block->ecdsa_block.signature,
       &block->ecdsa_block.derived_key);
+    break;
   case GNUNET_GNSRECORD_TYPE_EDKEY:
-    return GNUNET_CRYPTO_eddsa_verify_ (
+    purp->expiration_time = block->eddsa_block.expiration_time;
+    res = GNUNET_CRYPTO_eddsa_verify_ (
       GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN,
-      &block->eddsa_block.purpose,
+      &purp->purpose,
       &block->eddsa_block.signature,
       &block->eddsa_block.derived_key);
+    break;
   default:
-    return GNUNET_NO;
+    res = GNUNET_NO;
   }
+  GNUNET_free (purp);
+  return res;
 }
 
 
 enum GNUNET_GenericReturnValue
-block_decrypt_ecdsa (const struct GNUNET_GNSRECORD_EcdsaBlock *block,
+block_decrypt_ecdsa (const struct GNUNET_GNSRECORD_Block *block,
                      const struct
                      GNUNET_CRYPTO_EcdsaPublicKey *zone_key,
                      const char *label,
                      GNUNET_GNSRECORD_RecordCallback proc,
                      void *proc_cls)
 {
-  size_t payload_len = ntohl (block->purpose.size)
-                       - sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
-                       - sizeof(struct GNUNET_TIME_AbsoluteNBO);
+  size_t payload_len = ntohl (block->size) - sizeof (struct
+                                                     GNUNET_GNSRECORD_Block);
   unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2];
   unsigned char key[GNUNET_CRYPTO_AES_KEY_LENGTH];
 
-  if (ntohl (block->purpose.size) <
+  if (ntohl (block->size) <
       sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
       + sizeof(struct GNUNET_TIME_AbsoluteNBO))
   {
@@ -594,20 +644,18 @@ block_decrypt_ecdsa (const struct 
GNUNET_GNSRECORD_EcdsaBlock *block,
   GNR_derive_block_aes_key (ctr,
                             key,
                             label,
-                            block->expiration_time.abs_value_us__,
+                            block->ecdsa_block.expiration_time.abs_value_us__,
                             zone_key);
   {
     char payload[payload_len];
-    uint32_t rd_count;
+    unsigned int rd_count;
 
     GNUNET_break (payload_len ==
                   ecdsa_symmetric_decrypt (&block[1], payload_len,
                                            key, ctr,
                                            payload));
-    GNUNET_memcpy (&rd_count,
-                   payload,
-                   sizeof(uint32_t));
-    rd_count = ntohl (rd_count);
+    rd_count = GNUNET_GNSRECORD_records_deserialize_get_size (payload_len,
+                                                              payload);
     if (rd_count > 2048)
     {
       /* limit to sane value */
@@ -620,8 +668,8 @@ block_decrypt_ecdsa (const struct 
GNUNET_GNSRECORD_EcdsaBlock *block,
       struct GNUNET_TIME_Absolute now;
 
       if (GNUNET_OK !=
-          GNUNET_GNSRECORD_records_deserialize (payload_len - sizeof(uint32_t),
-                                                &payload[sizeof(uint32_t)],
+          GNUNET_GNSRECORD_records_deserialize (payload_len,
+                                                payload,
                                                 rd_count,
                                                 rd))
       {
@@ -699,20 +747,20 @@ block_decrypt_ecdsa (const struct 
GNUNET_GNSRECORD_EcdsaBlock *block,
 
 
 enum GNUNET_GenericReturnValue
-block_decrypt_eddsa (const struct GNUNET_GNSRECORD_EddsaBlock *block,
+block_decrypt_eddsa (const struct GNUNET_GNSRECORD_Block *block,
                      const struct
                      GNUNET_CRYPTO_EddsaPublicKey *zone_key,
                      const char *label,
                      GNUNET_GNSRECORD_RecordCallback proc,
                      void *proc_cls)
 {
-  size_t payload_len = ntohl (block->purpose.size)
-                       - sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
-                       - sizeof(struct GNUNET_TIME_AbsoluteNBO);
+  const struct GNUNET_GNSRECORD_EddsaBlock *edblock = &block->eddsa_block;
+  size_t payload_len = ntohl (block->size) - sizeof (struct
+                                                     GNUNET_GNSRECORD_Block);
   unsigned char nonce[crypto_secretbox_NONCEBYTES];
   unsigned char key[crypto_secretbox_KEYBYTES];
 
-  if (ntohl (block->purpose.size) <
+  if (ntohl (block->size) <
       sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
       + sizeof(struct GNUNET_TIME_AbsoluteNBO))
   {
@@ -722,20 +770,19 @@ block_decrypt_eddsa (const struct 
GNUNET_GNSRECORD_EddsaBlock *block,
   GNR_derive_block_xsalsa_key (nonce,
                                key,
                                label,
-                               block->expiration_time.abs_value_us__,
+                               
block->eddsa_block.expiration_time.abs_value_us__,
                                zone_key);
   {
     char payload[payload_len];
-    uint32_t rd_count;
+    unsigned int rd_count;
 
     GNUNET_break (GNUNET_OK ==
                   eddsa_symmetric_decrypt (&block[1], payload_len,
                                            key, nonce,
                                            payload));
-    GNUNET_memcpy (&rd_count,
-                   payload,
-                   sizeof(uint32_t));
-    rd_count = ntohl (rd_count);
+    payload_len -= crypto_secretbox_MACBYTES;
+    rd_count = GNUNET_GNSRECORD_records_deserialize_get_size (payload_len,
+                                                              payload);
     if (rd_count > 2048)
     {
       /* limit to sane value */
@@ -748,8 +795,8 @@ block_decrypt_eddsa (const struct 
GNUNET_GNSRECORD_EddsaBlock *block,
       struct GNUNET_TIME_Absolute now;
 
       if (GNUNET_OK !=
-          GNUNET_GNSRECORD_records_deserialize (payload_len - sizeof(uint32_t),
-                                                &payload[sizeof(uint32_t)],
+          GNUNET_GNSRECORD_records_deserialize (payload_len,
+                                                payload,
                                                 rd_count,
                                                 rd))
       {
@@ -852,12 +899,12 @@ GNUNET_GNSRECORD_block_decrypt (const struct 
GNUNET_GNSRECORD_Block *block,
   switch (ntohl (zone_key->type))
   {
   case GNUNET_IDENTITY_TYPE_ECDSA:
-    res = block_decrypt_ecdsa (&block->ecdsa_block,
+    res = block_decrypt_ecdsa (block,
                                &zone_key->ecdsa_key, norm_label, proc,
                                proc_cls);
     break;
   case GNUNET_IDENTITY_TYPE_EDDSA:
-    res = block_decrypt_eddsa (&block->eddsa_block,
+    res = block_decrypt_eddsa (block,
                                &zone_key->eddsa_key, norm_label, proc,
                                proc_cls);
     break;
diff --git a/src/gnsrecord/gnsrecord_crypto.h b/src/gnsrecord/gnsrecord_crypto.h
index be762f1b5..79a7e6fb9 100644
--- a/src/gnsrecord/gnsrecord_crypto.h
+++ b/src/gnsrecord/gnsrecord_crypto.h
@@ -34,6 +34,26 @@
 #include "gnunet_dnsparser_lib.h"
 #include "gnunet_tun_lib.h"
 
+/**
+ * Information we have in an encrypted block with record data (i.e. in the 
DHT).
+ */
+struct GNRBlockPS
+{
+  /**
+   * Number of bytes signed; also specifies the number of bytes
+   * of encrypted data that follow.
+   */
+  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+
+  /**
+   * Expiration time of the block.
+   */
+  struct GNUNET_TIME_AbsoluteNBO expiration_time;
+
+  /* followed by encrypted data */
+};
+
+
 /**
  * Derive session key and iv from label and public key.
  *
diff --git a/src/gnsrecord/gnsrecord_misc.c b/src/gnsrecord/gnsrecord_misc.c
index c6f07ccd0..61604c730 100644
--- a/src/gnsrecord/gnsrecord_misc.c
+++ b/src/gnsrecord/gnsrecord_misc.c
@@ -334,24 +334,7 @@ GNUNET_GNSRECORD_is_zonekey_type (uint32_t type)
 size_t
 GNUNET_GNSRECORD_block_get_size (const struct GNUNET_GNSRECORD_Block *block)
 {
-  switch (ntohl (block->type))
-  {
-  case GNUNET_GNSRECORD_TYPE_PKEY:
-    return sizeof (uint32_t)   /* zone type */
-           + sizeof (block->ecdsa_block)   /* EcdsaBlock */
-           + ntohl (block->ecdsa_block.purpose.size)   /* Length of signed 
data */
-           - sizeof (block->ecdsa_block.purpose);   /* Purpose already in 
EcdsaBlock */
-    break;
-  case GNUNET_GNSRECORD_TYPE_EDKEY:
-    return sizeof (uint32_t)   /* zone type */
-           + sizeof (block->eddsa_block)   /* EddsaBlock */
-           + ntohl (block->eddsa_block.purpose.size)   /* Length of signed 
data */
-           - sizeof (block->ecdsa_block.purpose);   /* Purpose already in 
EcdsaBlock */
-
-  default:
-    return 0;
-  }
-  return 0;
+  return ntohl (block->size);
 }
 
 
diff --git a/src/gnsrecord/gnsrecord_serialization.c 
b/src/gnsrecord/gnsrecord_serialization.c
index cb6957605..eaa3a9ab2 100644
--- a/src/gnsrecord/gnsrecord_serialization.c
+++ b/src/gnsrecord/gnsrecord_serialization.c
@@ -60,17 +60,18 @@ struct NetworkRecord
   /**
    * Number of bytes in 'data', network byte order.
    */
-  uint32_t data_size GNUNET_PACKED;
+  uint16_t data_size GNUNET_PACKED;
 
   /**
-   * Type of the GNS/DNS record, network byte order.
+   * Flags for the record, network byte order.
    */
-  uint32_t record_type GNUNET_PACKED;
+  uint16_t flags GNUNET_PACKED;
 
   /**
-   * Flags for the record, network byte order.
+   * Type of the GNS/DNS record, network byte order.
    */
-  uint32_t flags GNUNET_PACKED;
+  uint32_t record_type GNUNET_PACKED;
+
 };
 
 GNUNET_NETWORK_STRUCT_END
@@ -169,9 +170,9 @@ GNUNET_GNSRECORD_records_serialize (unsigned int rd_count,
          rd[i].flags,
          (unsigned long long) rd[i].expiration_time);
     rec.expiration_time = GNUNET_htonll (rd[i].expiration_time);
-    rec.data_size = htonl ((uint32_t) rd[i].data_size);
+    rec.data_size = htons ((uint16_t) rd[i].data_size);
     rec.record_type = htonl (rd[i].record_type);
-    rec.flags = htonl (rd[i].flags);
+    rec.flags = htons (rd[i].flags);
     if ((off + sizeof(rec) > dest_size) ||
         (off + sizeof(rec) < off))
     {
@@ -214,13 +215,48 @@ GNUNET_GNSRECORD_records_serialize (unsigned int rd_count,
   return dest_size;
 }
 
+unsigned int
+GNUNET_GNSRECORD_records_deserialize_get_size (size_t len,
+                                               const char *src)
+{
+  struct NetworkRecord rec;
+  struct NetworkRecord rec_zero;
+  size_t off;
+  unsigned int rd_count = 0;
+
+  memset (&rec_zero, 0, sizeof (rec_zero));
+
+  off = 0;
+  for (off = 0; (off + sizeof(rec) <= len) && (off + sizeof(rec) >= off);)
+  {
+    /*
+     * If we have found a byte string of zeroes, we have reached
+     * the padding
+     */
+    if (0 == GNUNET_memcmp (&rec, &rec_zero))
+      break;
+    GNUNET_memcpy (&rec,
+                   &src[off],
+                   sizeof(rec));
+    off += sizeof(rec);
+    if ((off + ntohs ((uint16_t) rec.data_size) > len) ||
+        (off + ntohs ((uint16_t) rec.data_size) < off))
+    {
+      GNUNET_break_op (0);
+      return 0;
+    }
+    off += ntohs ((uint16_t) rec.data_size);
+    rd_count++;
+  }
+  return rd_count;
+}
 
 /**
  * Deserialize the given records to the given destination.
  *
  * @param len size of the serialized record data
  * @param src the serialized record data
- * @param rd_count number of records in the rd array
+ * @param rd_count number of records parsed
  * @param dest where to put the data
  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
  */
@@ -246,9 +282,9 @@ GNUNET_GNSRECORD_records_deserialize (size_t len,
                    &src[off],
                    sizeof(rec));
     dest[i].expiration_time = GNUNET_ntohll (rec.expiration_time);
-    dest[i].data_size = ntohl ((uint32_t) rec.data_size);
+    dest[i].data_size = ntohs ((uint16_t) rec.data_size);
     dest[i].record_type = ntohl (rec.record_type);
-    dest[i].flags = ntohl (rec.flags);
+    dest[i].flags = ntohs (rec.flags);
     off += sizeof(rec);
     if ((off + dest[i].data_size > len) ||
         (off + dest[i].data_size < off))
diff --git a/src/gnsrecord/gnunet-gnsrecord-tvg.c 
b/src/gnsrecord/gnunet-gnsrecord-tvg.c
index 91c6608cd..f9b83e48b 100644
--- a/src/gnsrecord/gnunet-gnsrecord-tvg.c
+++ b/src/gnsrecord/gnunet-gnsrecord-tvg.c
@@ -38,12 +38,12 @@
 #define TEST_RRCOUNT 2
 
 static char *d_pkey =
-"50d7b652a4efeadff37396909785e5952171a02178c8e7d450fa907925fafd98";
+  "50d7b652a4efeadff37396909785e5952171a02178c8e7d450fa907925fafd98";
 
 static char *d_edkey =
-"5af7020ee19160328832352bbc6a68a8d71a7cbe1b929969a7c66d415a0d8f65";
+  "5af7020ee19160328832352bbc6a68a8d71a7cbe1b929969a7c66d415a0d8f65";
 
-int parsehex(char *src, char *dst, size_t dstlen, int invert)
+int parsehex (char *src, char *dst, size_t dstlen, int invert)
 {
   char *line = src;
   char *data = line;
@@ -51,7 +51,8 @@ int parsehex(char *src, char *dst, size_t dstlen, int invert)
   int read_byte;
   int data_len = 0;
 
-  while (sscanf(data, " %02x%n", &read_byte, &off) == 1) {
+  while (sscanf (data, " %02x%n", &read_byte, &off) == 1)
+  {
     if (invert)
       dst[dstlen - 1 - data_len++] = read_byte;
     else
@@ -155,9 +156,9 @@ run_pkey (void)
 
   id_priv.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY);
   GNUNET_CRYPTO_ecdsa_key_create (&id_priv.ecdsa_key);
-  parsehex(d_pkey,
-           (char*)&id_priv.ecdsa_key,
-           sizeof (id_priv.ecdsa_key), 1);
+  parsehex (d_pkey,
+            (char*) &id_priv.ecdsa_key,
+            sizeof (id_priv.ecdsa_key), 1);
 
   GNUNET_IDENTITY_key_get_public (&id_priv,
                                   &id_pub);
@@ -204,16 +205,12 @@ run_pkey (void)
   rdata_size = GNUNET_GNSRECORD_records_get_size (TEST_RRCOUNT,
                                                   rd);
   rdata = GNUNET_malloc (rdata_size);
-  rd_count_nbo = htonl (2);
-  GNUNET_memcpy (rdata,
-                 &rd_count_nbo,
-                 sizeof (uint32_t));
   GNUNET_GNSRECORD_records_serialize (2,
                                       rd,
                                       rdata_size,
-                                      rdata + sizeof (uint32_t));
+                                      rdata);
   fprintf (stdout, "RDATA:\n");
-  print_bytes (rdata, rdata_size + sizeof (uint32_t), 8);
+  print_bytes (rdata, rdata_size, 8);
   fprintf (stdout, "\n");
   expire = GNUNET_GNSRECORD_record_get_expiration_time (TEST_RRCOUNT, rd);
   GNR_derive_block_aes_key (ctr,
@@ -235,26 +232,20 @@ run_pkey (void)
   fprintf (stdout, "Storage key (q):\n");
   print_bytes (&query, sizeof (query), 8);
   fprintf (stdout, "\n");
-
-  rrblock = GNUNET_GNSRECORD_block_create (&id_priv,
-                                           expire,
-                                           TEST_RECORD_LABEL,
-                                           rd,
-                                           TEST_RRCOUNT);
-  size_t bdata_size = ntohl (rrblock->ecdsa_block.purpose.size)
-                      - sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
-                      - sizeof(struct GNUNET_TIME_AbsoluteNBO);
-  size_t ecblock_size = ntohl (rrblock->ecdsa_block.purpose.size)
-                        + sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)
-                        + sizeof(struct GNUNET_CRYPTO_EcdsaSignature);
-  size_t block_size = ecblock_size + sizeof (uint32_t);
+  GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create (&id_priv,
+                                                             expire,
+                                                             TEST_RECORD_LABEL,
+                                                             rd,
+                                                             TEST_RRCOUNT,
+                                                             &rrblock));
+  size_t bdata_size = ntohl(rrblock->size) - sizeof (struct 
GNUNET_GNSRECORD_Block);
 
   bdata = (char*) &(&rrblock->ecdsa_block)[1];
   fprintf (stdout, "BDATA:\n");
   print_bytes (bdata, bdata_size, 8);
   fprintf (stdout, "\n");
   fprintf (stdout, "RRBLOCK:\n");
-  print_bytes (rrblock, block_size, 8);
+  print_bytes (rrblock, ntohl(rrblock->size), 8);
   fprintf (stdout, "\n");
   GNUNET_free (rdata);
 }
@@ -309,9 +300,9 @@ run_edkey (void)
 
   id_priv.type = htonl (GNUNET_IDENTITY_TYPE_EDDSA);
   GNUNET_CRYPTO_eddsa_key_create (&id_priv.eddsa_key);
-  parsehex(d_edkey,
-           (char*)&id_priv.eddsa_key,
-           sizeof (id_priv.eddsa_key), 0);
+  parsehex (d_edkey,
+            (char*) &id_priv.eddsa_key,
+            sizeof (id_priv.eddsa_key), 0);
   GNUNET_IDENTITY_key_get_public (&id_priv,
                                   &id_pub);
   fprintf (stdout,
@@ -358,17 +349,13 @@ run_edkey (void)
                                                   rd);
   expire = GNUNET_GNSRECORD_record_get_expiration_time (TEST_RRCOUNT,
                                                         rd);
-  rdata = GNUNET_malloc (sizeof (uint32_t) + rdata_size);
-  rd_count_nbo = htonl (2);
-  GNUNET_memcpy (rdata,
-                 &rd_count_nbo,
-                 sizeof (uint32_t));
+  rdata = GNUNET_malloc (rdata_size);
   GNUNET_GNSRECORD_records_serialize (2,
                                       rd,
                                       rdata_size,
-                                      rdata + sizeof (uint32_t));
+                                      rdata);
   fprintf (stdout, "RDATA:\n");
-  print_bytes (rdata, rdata_size + sizeof (uint32_t), 8);
+  print_bytes (rdata, rdata_size, 8);
   fprintf (stdout, "\n");
   GNR_derive_block_xsalsa_key (nonce,
                                skey,
@@ -389,25 +376,20 @@ run_edkey (void)
   print_bytes (&query, sizeof (query), 8);
   fprintf (stdout, "\n");
 
-  rrblock = GNUNET_GNSRECORD_block_create (&id_priv,
-                                           expire,
-                                           TEST_RECORD_LABEL,
-                                           rd,
-                                           TEST_RRCOUNT);
-  size_t bdata_size = ntohl (rrblock->eddsa_block.purpose.size)
-                      - sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
-                      - sizeof(struct GNUNET_TIME_AbsoluteNBO);
-  size_t ecblock_size = ntohl (rrblock->eddsa_block.purpose.size)
-                        + sizeof(struct GNUNET_CRYPTO_EddsaPublicKey)
-                        + sizeof(struct GNUNET_CRYPTO_EddsaSignature);
-  size_t block_size = ecblock_size + sizeof (uint32_t);
+  GNUNET_assert (GNUNET_OK ==  GNUNET_GNSRECORD_block_create (&id_priv,
+                                                              expire,
+                                                              
TEST_RECORD_LABEL,
+                                                              rd,
+                                                              TEST_RRCOUNT,
+                                                              &rrblock));
+  size_t bdata_size = ntohl(rrblock->size) - sizeof (struct 
GNUNET_GNSRECORD_Block);
 
   bdata = (char*) &(&rrblock->eddsa_block)[1];
   fprintf (stdout, "BDATA:\n");
   print_bytes (bdata, bdata_size, 8);
   fprintf (stdout, "\n");
   fprintf (stdout, "RRBLOCK:\n");
-  print_bytes (rrblock, block_size, 8);
+  print_bytes (rrblock, ntohl(rrblock->size), 8);
   fprintf (stdout, "\n");
   GNUNET_free (rdata);
 }
diff --git a/src/gnsrecord/test_gnsrecord_crypto.c 
b/src/gnsrecord/test_gnsrecord_crypto.c
index 9e5a1aa7e..ee14fa904 100644
--- a/src/gnsrecord/test_gnsrecord_crypto.c
+++ b/src/gnsrecord/test_gnsrecord_crypto.c
@@ -123,12 +123,12 @@ test_with_type (struct GNUNET_IDENTITY_PrivateKey 
*privkey)
   s_rd = create_record (RECORDS);
 
   /* Create block */
-  GNUNET_assert (NULL != (block =
-                            GNUNET_GNSRECORD_block_create (privkey,
-                                                           expire,
-                                                           s_name,
-                                                           s_rd,
-                                                           RECORDS)));
+  GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create (privkey,
+                                                             expire,
+                                                             s_name,
+                                                             s_rd,
+                                                             RECORDS,
+                                                             &block));
   GNUNET_assert (GNUNET_OK ==
                  GNUNET_GNSRECORD_query_from_block (block,
                                                     &query_block));
diff --git a/src/include/gnunet_gnsrecord_lib.h 
b/src/include/gnunet_gnsrecord_lib.h
index 94e20323d..fdbac3cf5 100644
--- a/src/include/gnunet_gnsrecord_lib.h
+++ b/src/include/gnunet_gnsrecord_lib.h
@@ -61,6 +61,7 @@ extern "C" {
 
 /**
  * Flags that can be set for a record.
+ * MUST fit into 16 bit.
  */
 enum GNUNET_GNSRECORD_Flags
 {
@@ -70,10 +71,17 @@ enum GNUNET_GNSRECORD_Flags
   GNUNET_GNSRECORD_RF_NONE = 0,
 
   /**
-   * This is a private record of this peer and it should
-   * thus not be handed out to other peers.
+   * This record is critical. If it cannot be processed
+   * (for example beacuse the record type is unknown)
+   * resolution MUST fail
    */
-  GNUNET_GNSRECORD_RF_PRIVATE = 2,
+  GNUNET_GNSRECORD_RF_CRITICAL = 1,
+
+  /**
+   * This record should not be used unless all (other) records with an absolute
+   * expiration time have expired.
+   */
+  GNUNET_GNSRECORD_RF_SHADOW_RECORD = 2,
 
   /**
    * This is a supplemental record.
@@ -84,13 +92,14 @@ enum GNUNET_GNSRECORD_Flags
    * This expiration time of the record is a relative
    * time (not an absolute time).
    */
-  GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION = 8,
+  GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION = 16384, /* 2^14 */
 
   /**
-   * This record should not be used unless all (other) records with an absolute
-   * expiration time have expired.
+   * This is a private record of this peer and it should
+   * thus not be handed out to other peers.
    */
-  GNUNET_GNSRECORD_RF_SHADOW_RECORD = 16
+  GNUNET_GNSRECORD_RF_PRIVATE = 32768, /* 2^15 */
+
 
 /**
  * When comparing flags for record equality for removal,
@@ -183,12 +192,6 @@ struct GNUNET_GNSRECORD_EcdsaBlock
    */
   struct GNUNET_CRYPTO_EcdsaSignature signature;
 
-  /**
-   * Number of bytes signed; also specifies the number of bytes
-   * of encrypted data that follow.
-   */
-  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
   /**
    * Expiration time of the block.
    */
@@ -213,23 +216,26 @@ struct GNUNET_GNSRECORD_EddsaBlock
    */
   struct GNUNET_CRYPTO_EddsaSignature signature;
 
-  /**
-   * Number of bytes signed; also specifies the number of bytes
-   * of encrypted data that follow.
-   */
-  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
   /**
    * Expiration time of the block.
    */
   struct GNUNET_TIME_AbsoluteNBO expiration_time;
 
+
   /* followed by encrypted data */
 };
 
 
 struct GNUNET_GNSRECORD_Block
 {
+  /**
+   * Size of the block.
+   */
+  uint32_t size;
+
+  /**
+   * The zone type (GNUNET_GNSRECORD_TYPE_PKEY)
+   */
   uint32_t type;
 
   union
@@ -387,6 +393,9 @@ GNUNET_GNSRECORD_records_serialize (unsigned int rd_count,
                                     const struct GNUNET_GNSRECORD_Data *rd,
                                     size_t dest_size, char *dest);
 
+unsigned int
+GNUNET_GNSRECORD_records_deserialize_get_size (size_t len,
+                                               const char *src);
 
 /**
  * Deserialize the given records to the given destination.
@@ -502,6 +511,21 @@ GNUNET_GNSRECORD_query_from_public_key (
   struct GNUNET_HashCode *query);
 
 
+/**
+ * Get size of buffer for block creation.
+ *
+ * @param key the zone key
+ * @param rd record data
+ * @param rd_count number of records
+ * @return -1 on error (otherwise the length of the block)
+ */
+ssize_t
+GNUNET_GNSRECORD_block_calculate_size (const struct
+                                       GNUNET_IDENTITY_PrivateKey *key,
+                                       const struct GNUNET_GNSRECORD_Data *rd,
+                                       unsigned int rd_count);
+
+
 /**
  * Sign name and records
  *
@@ -510,13 +534,16 @@ GNUNET_GNSRECORD_query_from_public_key (
  * @param label the name for the records
  * @param rd record data
  * @param rd_count number of records in @a rd
+ * @param result the block buffer. Will be allocated.
+ * @return GNUNET_OK on success
  */
-struct GNUNET_GNSRECORD_Block *
+enum GNUNET_GenericReturnValue
 GNUNET_GNSRECORD_block_create (const struct GNUNET_IDENTITY_PrivateKey *key,
                                struct GNUNET_TIME_Absolute expire,
                                const char *label,
                                const struct GNUNET_GNSRECORD_Data *rd,
-                               unsigned int rd_count);
+                               unsigned int rd_count,
+                               struct GNUNET_GNSRECORD_Block **block);
 
 
 /**
@@ -529,13 +556,16 @@ GNUNET_GNSRECORD_block_create (const struct 
GNUNET_IDENTITY_PrivateKey *key,
  * @param label the name for the records
  * @param rd record data
  * @param rd_count number of records in @a rd
+ * @param result the block buffer. Will be allocated.
+ * @return GNUNET_OK on success.
  */
-struct GNUNET_GNSRECORD_Block *
+enum GNUNET_GenericReturnValue
 GNUNET_GNSRECORD_block_create2 (const struct GNUNET_IDENTITY_PrivateKey *key,
                                 struct GNUNET_TIME_Absolute expire,
                                 const char *label,
                                 const struct GNUNET_GNSRECORD_Data *rd,
-                                unsigned int rd_count);
+                                unsigned int rd_count,
+                                struct GNUNET_GNSRECORD_Block **result);
 
 
 /**

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]