gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r28546 - in gnunet/src: . include namestore


From: gnunet
Subject: [GNUnet-SVN] r28546 - in gnunet/src: . include namestore
Date: Mon, 12 Aug 2013 21:09:52 +0200

Author: grothoff
Date: 2013-08-12 21:09:52 +0200 (Mon, 12 Aug 2013)
New Revision: 28546

Modified:
   gnunet/src/Makefile.am
   gnunet/src/include/gnunet_namestore_plugin.h
   gnunet/src/include/gnunet_namestore_service.h
   gnunet/src/include/gnunet_protocols.h
   gnunet/src/namestore/Makefile.am
   gnunet/src/namestore/gnunet-namestore.c
   gnunet/src/namestore/namestore.h
   gnunet/src/namestore/namestore_api.c
   gnunet/src/namestore/namestore_api_common.c
   gnunet/src/namestore/namestore_api_monitor.c
   gnunet/src/namestore/plugin_namestore_sqlite.c
Log:
-towards namestore support for the new privacy-preserving GNS queries

Modified: gnunet/src/Makefile.am
===================================================================
--- gnunet/src/Makefile.am      2013-08-12 18:00:43 UTC (rev 28545)
+++ gnunet/src/Makefile.am      2013-08-12 19:09:52 UTC (rev 28546)
@@ -10,15 +10,17 @@
 endif
 
 if HAVE_EXPERIMENTAL
- EXP_DIR = dv $(CONSENSUS) $(EXPERIMENTATION)
+ EXP_DIR = dv $(CONSENSUS) $(EXPERIMENTATION) 
 endif
 
 if LINUX
 # All of these currently only work on GNU/Linux or W32
- LINUX_DIR = exit vpn pt
+ LINUX_DIR = exit vpn
+# pt # without namestore, pt currently has some issues...
 endif
 if MINGW
- MINGW_DIR = vpn exit pt
+ MINGW_DIR = vpn exit 
+# pt # without namestore, pt currently has some issues...
 endif
 
 if HAVE_MYSQL
@@ -44,7 +46,6 @@
   $(POSTGRES_DIR) \
   datacache \
   datastore \
-  namestore \
   template \
   ats \
   nat \
@@ -67,6 +68,7 @@
   fs \
   $(LINUX_DIR) \
   $(MINGW_DIR) \
-  gns \
   integration-tests \
   $(EXP_DIR) 
+
+# note: namestore, gns are not listed right now as they are being reworked to 
use the new crypto
\ No newline at end of file

Modified: gnunet/src/include/gnunet_namestore_plugin.h
===================================================================
--- gnunet/src/include/gnunet_namestore_plugin.h        2013-08-12 18:00:43 UTC 
(rev 28545)
+++ gnunet/src/include/gnunet_namestore_plugin.h        2013-08-12 19:09:52 UTC 
(rev 28546)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet
-     (C) 2012 Christian Grothoff (and other contributing authors)
+     (C) 2012, 2013 Christian Grothoff (and other contributing authors)
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
@@ -40,25 +40,29 @@
 
 
 /**
+ * Function called for matching blocks.
+ *
+ * @param cls closure
+ * @param block lookup result
+ */
+typedef void (*GNUNET_NAMESTORE_BlockCallback) (void *cls,
+                                               const struct 
GNUNET_NAMESTORE_Block *block);
+
+
+/**
  * Function called by for each matching record.
  *
  * @param cls closure
- * @param zone_key public key of the zone
- * @param expire when does the corresponding block in the DHT expire (until
- *               when should we never do a DHT lookup for the same name again)?
- * @param name name that is being mapped (at most 255 characters long)
+ * @param zone_key private key of the zone
+ * @param label name that is being mapped (at most 255 characters long)
  * @param rd_count number of entries in 'rd' array
  * @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)
  */
 typedef void (*GNUNET_NAMESTORE_RecordIterator) (void *cls,
-                                                const struct 
GNUNET_CRYPTO_EccPublicKey *zone_key,
-                                                struct GNUNET_TIME_Absolute 
expire,
-                                                const char *name,
-                                                unsigned int rd_len,
-                                                const struct 
GNUNET_NAMESTORE_RecordData *rd,
-                                                const struct 
GNUNET_CRYPTO_EccSignature *signature);
+                                                const struct 
GNUNET_CRYPTO_EccPrivateKey *private_key,
+                                                const char *label,
+                                                unsigned int rd_count,
+                                                const struct 
GNUNET_NAMESTORE_RecordData *rd);
 
 
 /**
@@ -73,49 +77,58 @@
   void *cls;
 
   /**
-   * Store a record in the datastore.  Removes any existing record in the
-   * same zone with the same name.
+   * Cache a block in the datastore. Overwrites (older) existing blocks
+   * for the same zone and label.
    *
    * @param cls closure (internal context for the plugin)
-   * @param zone_key public key of the zone
-   * @param expire when does the corresponding block in the DHT expire (until
-   *               when should we never do a DHT lookup for the same name 
again)?
-   * @param name name that is being mapped (at most 255 characters long)
-   * @param rd_count number of entries in 'rd' array
-   * @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)
+   * @param block block to cache
    * @return GNUNET_OK on success, else GNUNET_SYSERR
    */
-  int (*put_records) (void *cls, 
-                     const struct GNUNET_CRYPTO_EccPublicKey *zone_key,
-                     struct GNUNET_TIME_Absolute expire,
-                     const char *name,
-                     unsigned int rd_len,
-                     const struct GNUNET_NAMESTORE_RecordData *rd,
-                     const struct GNUNET_CRYPTO_EccSignature *signature);
+  int (*cache_block) (void *cls, 
+                     const struct GNUNET_NAMESTORE_Block *block);
 
 
   /**
-   * Removes any existing record in the given zone with the same name.
+   * Get the block for a particular zone and label in the
+   * datastore.  Will return at most one result to the iterator.
    *
    * @param cls closure (internal context for the plugin)
-   * @param zone hash of the public key of the zone
-   * @param name name to remove (at most 255 characters long)
-   * @return GNUNET_OK on success
+   * @param query hash of public key derived from the zone and the label
+   * @param iter function to call with the result
+   * @param iter_cls closure for iter
+   * @return GNUNET_OK on success, GNUNET_NO if there were no results, 
GNUNET_SYSERR on error
+   *         'iter' will have been called unless the return value is 
'GNUNET_SYSERR'
    */
-  int (*remove_records) (void *cls, 
-                        const struct GNUNET_CRYPTO_ShortHashCode *zone,
-                        const char *name);
+  int (*lookup_block) (void *cls, 
+                      const struct GNUNET_HashCode *query,
+                      GNUNET_NAMESTORE_BlockCallback iter, void *iter_cls);
 
 
+
   /**
-   * Iterate over the results for a particular key and zone in the
+   * Store a record in the datastore for which we are the authority.
+   * Removes any existing record in the same zone with the same name.
+   *
+   * @param cls closure (internal context for the plugin)
+   * @param zone private key of the zone
+   * @param label name of the record in the zone
+   * @param rd_count number of entries in 'rd' array, 0 to delete all records
+   * @param rd array of records with data to store
+   * @return GNUNET_OK on success, else GNUNET_SYSERR
+   */
+  int (*store_records) (void *cls, 
+                       const struct GNUNET_CRYPTO_EccPrivateKey *zone,
+                       const char *label,
+                       unsigned int rd_count,
+                       const struct GNUNET_NAMESTORE_RecordData *rd);
+
+
+  /**
+   * Iterate over the results for a particular zone in the
    * datastore.  Will return at most one result to the iterator.
    *
    * @param cls closure (internal context for the plugin)
-   * @param zone hash of public key of the zone, NULL to iterate over all zones
-   * @param name name as '\0' terminated string, NULL to iterate over all 
records of the zone
+   * @param zone private key of the zone
    * @param offset offset in the list of all matching records
    * @param iter function to call with the result
    * @param iter_cls closure for iter
@@ -123,8 +136,7 @@
    *       'iter' will have been called unless the return value is 
'GNUNET_SYSERR'
    */
   int (*iterate_records) (void *cls, 
-                         const struct GNUNET_CRYPTO_ShortHashCode *zone,
-                         const char *name,
+                         const struct GNUNET_CRYPTO_EccPrivateKey *zone,
                          uint64_t offset,
                          GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls);
 
@@ -134,29 +146,19 @@
    * Returns at most one result to the iterator.
    *
    * @param cls closure (internal context for the plugin)
-   * @param zone hash of public key of the zone to look up in, never NULL
-   * @param value_zone hash of the public key of the target zone (value), 
never NULL
+   * @param zone private key of the zone to look up in, never NULL
+   * @param value_zone public key of the target zone (value), never NULL
    * @param iter function to call with the result
    * @param iter_cls closure for iter
    * @return GNUNET_OK on success, GNUNET_NO if there were no results, 
GNUNET_SYSERR on error
    *       'iter' will have been called unless the return value is 
'GNUNET_SYSERR'
    */
   int (*zone_to_name) (void *cls, 
-                      const struct GNUNET_CRYPTO_ShortHashCode *zone,
-                      const struct GNUNET_CRYPTO_ShortHashCode *value_zone,
+                      const struct GNUNET_CRYPTO_EccPrivateKey *zone,
+                      const struct GNUNET_CRYPTO_EccPublicKey *value_zone,
                       GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls);
 
 
-  /**
-   * Delete an entire zone (all records).  Not used in normal operation.
-   *
-   * @param cls closure (internal context for the plugin)
-   * @param zone zone to delete
-   */
-  void (*delete_zone) (void *cls,
-                      const struct GNUNET_CRYPTO_ShortHashCode *zone);
-
-
 };
 
 

Modified: gnunet/src/include/gnunet_namestore_service.h
===================================================================
--- gnunet/src/include/gnunet_namestore_service.h       2013-08-12 18:00:43 UTC 
(rev 28545)
+++ gnunet/src/include/gnunet_namestore_service.h       2013-08-12 19:09:52 UTC 
(rev 28546)
@@ -21,12 +21,11 @@
 /**
  * @file include/gnunet_namestore_service.h
  * @brief API that can be used to store naming information on a GNUnet node;
+ *        Naming information can either be records for which this peer/user
+ *        is authoritative, or blocks which are cached, encrypted naming
+ *        data from other peers.
  * @author Christian Grothoff
- *
- * Other functions we might want:
- * - enumerate all known zones
  */
-
 #ifndef GNUNET_NAMESTORE_SERVICE_H
 #define GNUNET_NAMESTORE_SERVICE_H
 
@@ -97,7 +96,6 @@
 #define GNUNET_NAMESTORE_MAX_VALUE_SIZE (63 * 1024)
 
 
-
 /**
  * Connect to the namestore service.
  *
@@ -229,63 +227,61 @@
 
 
 /**
+ * Information we have in an encrypted block with record data (i.e. in the 
DHT).
+ */
+struct GNUNET_NAMESTORE_Block
+{
+
+  /**
+   * Signature of the block.
+   */
+  struct GNUNET_CRYPTO_EccSignature signature;
+
+  /**
+   * Derived key used for signing; hash of this is the query.
+   */
+  struct GNUNET_CRYPTO_EccPublicKey derived_key;
+
+  /**
+   * 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 */
+};
+
+
+/**
  * Store an item in the namestore.  If the item is already present,
- * it is replaced with the new record.  Use an empty array to
- * remove all records under the given name.
+ * it is replaced with the new record.  
  *
  * @param h handle to the namestore
- * @param zone_key public key of the zone
- * @param name name that is being mapped (at most 255 characters long)
- * @param freshness when does the corresponding block in the DHT expire (until
- *               when should we never do a DHT lookup for the same name again)?
- * @param rd_count number of entries in 'rd' array
- * @param rd array of records with data to store
- * @param signature signature for all the records in the zone under the given 
name
+ * @param block block to store
  * @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_record_put (struct GNUNET_NAMESTORE_Handle *h,
-                            const struct GNUNET_CRYPTO_EccPublicKey *zone_key,
-                            const char *name,
-                            struct GNUNET_TIME_Absolute freshness,
-                            unsigned int rd_count,
-                            const struct GNUNET_NAMESTORE_RecordData *rd,
-                            const struct GNUNET_CRYPTO_EccSignature *signature,
-                            GNUNET_NAMESTORE_ContinuationWithStatus cont,
-                            void *cont_cls);
+GNUNET_NAMESTORE_block_cache (struct GNUNET_NAMESTORE_Handle *h,
+                             const struct GNUNET_NAMESTORE_Block *block,
+                             GNUNET_NAMESTORE_ContinuationWithStatus cont,
+                             void *cont_cls);
 
 
 /**
- * Check if a signature is valid.  This API is used by the GNS Block
- * to validate signatures received from the network.
- *
- * @param public_key public key of the zone
- * @param freshness time set for block expiration
- * @param name name that is being mapped (at most 255 characters long)
- * @param rd_count number of entries in 'rd' array
- * @param rd array of records with data to store
- * @param signature signature for all the records in the zone under the given 
name
- * @return GNUNET_OK if the signature is valid
- */
-int
-GNUNET_NAMESTORE_verify_signature (const struct GNUNET_CRYPTO_EccPublicKey 
*public_key,
-                                   const struct GNUNET_TIME_Absolute freshness,
-                                   const char *name,
-                                   unsigned int rd_count,
-                                   const struct GNUNET_NAMESTORE_RecordData 
*rd,
-                                   const struct GNUNET_CRYPTO_EccSignature 
*signature);
-
-
-/**
  * Store an item in the namestore.  If the item is already present,
  * it is replaced with the new record.  Use an empty array to
  * remove all records under the given name.
  *
  * @param h handle to the namestore
  * @param pkey private key of the zone
- * @param name name that is being mapped (at most 255 characters long)
+ * @param label name that is being mapped (at most 255 characters long)
  * @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
@@ -293,76 +289,65 @@
  * @return handle to abort the request
  */
 struct GNUNET_NAMESTORE_QueueEntry *
-GNUNET_NAMESTORE_record_put_by_authority (struct GNUNET_NAMESTORE_Handle *h,
-                                         const struct 
GNUNET_CRYPTO_EccPrivateKey *pkey,
-                                         const char *name,
-                                         unsigned int rd_count,
-                                         const struct 
GNUNET_NAMESTORE_RecordData *rd,
-                                         
GNUNET_NAMESTORE_ContinuationWithStatus cont,
-                                         void *cont_cls);
+GNUNET_NAMESTORE_records_store (struct GNUNET_NAMESTORE_Handle *h,
+                               const struct GNUNET_CRYPTO_EccPrivateKey *pkey,
+                               const char *label,
+                               unsigned int rd_count,
+                               const struct GNUNET_NAMESTORE_RecordData *rd,
+                               GNUNET_NAMESTORE_ContinuationWithStatus cont,
+                               void *cont_cls);
 
 
 /**
  * Process a record that was stored in the namestore.
  *
  * @param cls closure
- * @param zone_key public key of the zone
- * @param freshness when does the corresponding block in the DHT expire (until
- *               when should we never do a DHT lookup for the same name 
again)?; 
- *               GNUNET_TIME_UNIT_ZERO_ABS if there are no records of any type 
in the namestore,
- *               or the expiration time of the block in the namestore (even if 
there are zero
- *               records matching the desired record type)
- * @param name name that is being mapped (at most 255 characters long)
- * @param rd_count number of entries in 'rd' array
- * @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)
+ * @param block block that was stored in the namestore
  */
-typedef void (*GNUNET_NAMESTORE_RecordProcessor) (void *cls,
-                                                 const struct 
GNUNET_CRYPTO_EccPublicKey *zone_key,
-                                                 struct GNUNET_TIME_Absolute 
freshness,                            
-                                                 const char *name,
-                                                 unsigned int rd_count,
-                                                 const struct 
GNUNET_NAMESTORE_RecordData *rd,
-                                                 const struct 
GNUNET_CRYPTO_EccSignature *signature);
+typedef void (*GNUNET_NAMESTORE_BlockProcessor) (void *cls,
+                                                const struct 
GNUNET_NAMESTORE_Block *block);
 
 
 /**
  * Get a result for a particular key from the namestore.  The processor
- * will only be called once.  When using this functions, relative expiration
- * times will be converted to absolute expiration times and a signature
- * will be created if we are the authority.  The record data and signature
- * passed to 'proc' is thus always suitable for passing on to other peers
- * (if we are the authority).  If the record type is NOT set to 'ANY' and
- * if we are NOT the authority, then non-matching records may be omitted
- * from the result and no valid signature can be created; in this case,
- * 'signature' will be NULL and the result cannot be given to other peers.
+ * will only be called once.  
  *
  * @param h handle to the namestore
- * @param zone zone to look up a record from
- * @param name name to look up
- * @param record_type desired record type, 0 for all
- * @param proc function to call on the matching records, or with
- *        NULL (rd_count == 0) if there are no matching records
+ * @param derived_hash hash of zone key combined with name to lookup
+ * @param proc function to call on the matching block, or with
+ *        NULL if there is no matching block
  * @param proc_cls closure for proc
- * @return a handle that can be used to
- *         cancel
+ * @return a handle that can be used to cancel
  */
 struct GNUNET_NAMESTORE_QueueEntry *
-GNUNET_NAMESTORE_lookup_record (struct GNUNET_NAMESTORE_Handle *h, 
-                               const struct GNUNET_CRYPTO_ShortHashCode *zone,
-                               const char *name,
-                               uint32_t record_type,
-                               GNUNET_NAMESTORE_RecordProcessor proc, void 
*proc_cls);
+GNUNET_NAMESTORE_lookup_block (struct GNUNET_NAMESTORE_Handle *h, 
+                              const struct GNUNET_HashCode *derived_hash,
+                              GNUNET_NAMESTORE_BlockProcessor proc, void 
*proc_cls);
 
 
 /**
+ * Process a record that was stored in the namestore.
+ *
+ * @param cls closure
+ * @param zone private key of the zone
+ * @param label label of the records
+ * @param rd_count number of entries in 'rd' array
+ * @param rd array of records with data to store
+ */
+typedef void (*GNUNET_NAMESTORE_RecordMonitor) (void *cls,
+                                               const struct 
GNUNET_CRYPTO_EccPrivateKey *zone,
+                                               const char *label,
+                                               unsigned int rd_count,
+                                               const struct 
GNUNET_NAMESTORE_RecordData *rd);
+
+
+/**
  * Look for an existing PKEY delegation record for a given public key.
  * Returns at most one result to the processor.
  *
  * @param h handle to the namestore
- * @param zone hash of public key of the zone to look up in, never NULL
- * @param value_zone hash of the public key of the target zone (value), never 
NULL
+ * @param zone public key of the zone to look up in, never NULL
+ * @param value_zone public key of the target zone (value), never NULL
  * @param proc function to call on the matching records, or with
  *        NULL (rd_count == 0) if there are no matching records
  * @param proc_cls closure for proc
@@ -371,9 +356,9 @@
  */
 struct GNUNET_NAMESTORE_QueueEntry *
 GNUNET_NAMESTORE_zone_to_name (struct GNUNET_NAMESTORE_Handle *h, 
-                              const struct GNUNET_CRYPTO_ShortHashCode *zone,
-                              const struct GNUNET_CRYPTO_ShortHashCode 
*value_zone,
-                              GNUNET_NAMESTORE_RecordProcessor proc, void 
*proc_cls);
+                              const struct GNUNET_CRYPTO_EccPrivateKey *zone,
+                              const struct GNUNET_CRYPTO_EccPublicKey 
*value_zone,
+                              GNUNET_NAMESTORE_RecordMonitor proc, void 
*proc_cls);
 
 
 /**
@@ -393,28 +378,8 @@
  * records into our DHT). "proc" will be called once immediately, and
  * then again after "GNUNET_NAMESTORE_zone_iterator_next" is invoked.
  *
- * By specifying a 'zone' of NULL and setting 'GNUNET_NAMESTORE_RF_AUTHORITY'
- * in 'must_have_flags', we can iterate over all records for which we are
- * the authority (the 'authority' flag will NOT be set in the returned
- * records anyway).  
- *
- * The 'GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION'
- * bit in 'must_have_flags' has a special meaning:
- *
- * 0) If the bit is clear, all relative expriation times are converted to
- *    absolute expiration times.  This is useful for performing DHT PUT
- *    operations (and zone transfers) of our zone.  The generated signatures
- *    will be valid for other peers.
- * 1) if it is set, it means that relative expiration times should be
- *    preserved when returned (this is useful for the zone editor user 
- *    interface).  No signatures will be created in this case, as 
- *    signatures must not cover records with relative expiration times.
- *
- * Note that not all queries against this interface are equally performant
- * as for some combinations no efficient index may exist.
- *
  * @param h handle to the namestore
- * @param zone zone to access, NULL for all zones
+ * @param zone zone to access
  * @param must_have_flags flags that must be set for the record to be returned
  * @param must_not_have_flags flags that must NOT be set for the record to be 
returned
  * @param proc function to call on each name from the zone; it
@@ -425,10 +390,8 @@
  */
 struct GNUNET_NAMESTORE_ZoneIterator *
 GNUNET_NAMESTORE_zone_iteration_start (struct GNUNET_NAMESTORE_Handle *h,
-                                      const struct GNUNET_CRYPTO_ShortHashCode 
*zone,
-                                      enum GNUNET_NAMESTORE_RecordFlags 
must_have_flags,
-                                      enum GNUNET_NAMESTORE_RecordFlags 
must_not_have_flags,
-                                      GNUNET_NAMESTORE_RecordProcessor proc,
+                                      const struct GNUNET_CRYPTO_EccPrivateKey 
*zone,
+                                      GNUNET_NAMESTORE_RecordMonitor proc,
                                       void *proc_cls);
 
 
@@ -460,35 +423,6 @@
 
 
 /**
- * Function called whenever the records for a given name changed.
- *
- * @param cls closure
- * @param zone_key NULL if the communication with the namestore broke down
- *                    (and thus all entries should be 'cleared' until the 
communication
- *                     can be re-established, at which point the monitor will 
- *                     re-add all records that are (still) in the namestore 
after
- *                     the reconnect); if this value is NULL, all other 
arguments
- *                     will also be 0/NULL.
- * @param freshness when does the corresponding block in the DHT expire (until
- *               when should we never do a DHT lookup for the same name 
again)?; 
- *               GNUNET_TIME_UNIT_ZERO_ABS if there are no records of any type 
in the namestore,
- *               or the expiration time of the block in the namestore (even if 
there are zero
- *               records matching the desired record type)
- * @param name name that is being mapped (at most 255 characters long)
- * @param rd_count number of entries in 'rd' array
- * @param rd array of records with data to store
- * @param signature signature of the record block
- */
-typedef void (*GNUNET_NAMESTORE_RecordMonitor)(void *cls,
-                                              const struct 
GNUNET_CRYPTO_EccPublicKey *zone_key,
-                                              struct GNUNET_TIME_Absolute 
freshness,                       
-                                              const char *name,
-                                              unsigned int rd_len,
-                                              const struct 
GNUNET_NAMESTORE_RecordData *rd,
-                                              const struct 
GNUNET_CRYPTO_EccSignature *signature);
-
-
-/**
  * Function called once the monitor has caught up with the current 
  * state of the database.  Will be called AGAIN after each disconnect
  * (record monitor called with 'NULL' for zone_key) once we're again
@@ -513,7 +447,7 @@
  * monitoring).
  *
  * @param cfg configuration to use to connect to namestore
- * @param zone zone to monitor, NULL for all zones
+ * @param zone zone to monitor
  * @param monitor function to call on zone changes
  * @param sync_cb function called when we're in sync with the namestore
  * @param cls closure for 'monitor' and 'sync_cb'
@@ -521,7 +455,7 @@
  */
 struct GNUNET_NAMESTORE_ZoneMonitor *
 GNUNET_NAMESTORE_zone_monitor_start (const struct GNUNET_CONFIGURATION_Handle 
*cfg,
-                                    const struct GNUNET_CRYPTO_ShortHashCode 
*zone,
+                                    const struct GNUNET_CRYPTO_EccPrivateKey 
*zone,
                                     GNUNET_NAMESTORE_RecordMonitor monitor,
                                     
GNUNET_NAMESTORE_RecordsSynchronizedCallback sync_cb,
                                     void *cls);
@@ -659,37 +593,92 @@
 
 
 /**
- * Convert a short hash to a string (for printing debug messages).
+ * Convert a zone to a string (for printing debug messages).
  * This is one of the very few calls in the entire API that is
  * NOT reentrant!
  *
- * @param hc the short hash code
+ * @param z public key of a zone
  * @return string form; will be overwritten by next call to GNUNET_h2s.
  */
 const char *
-GNUNET_NAMESTORE_short_h2s (const struct GNUNET_CRYPTO_ShortHashCode * hc);
+GNUNET_NAMESTORE_z2s (const struct GNUNET_CRYPTO_EccPublicKey *z);
 
 
 /**
+ * Calculate the DHT query for a given 'label' in a given zone.
+ * 
+ * @param zone private key of the zone
+ * @param label label of the record
+ * @return query hash to use for the query
+ */
+void
+GNUNET_NAMESTORE_query_from_private_key (const struct 
GNUNET_CRYPTO_EccPrivateKey *zone,
+                                        const char *label,
+                                        struct GNUNET_HashCode *query);
+
+
+/**
+ * Calculate the DHT query for a given 'label' in a given zone.
+ * 
+ * @param pub public key of the zone
+ * @param label label of the record
+ * @return query hash to use for the query
+ */
+void
+GNUNET_NAMESTORE_query_from_public_key (const struct 
GNUNET_CRYPTO_EccPublicKey *pub,
+                                       const char *label,
+                                       struct GNUNET_HashCode *query);
+
+
+/**
  * Sign name and records
  *
  * @param key the private key
  * @param expire block expiration
- * @param name the name
+ * @param label the name for the records
  * @param rd record data
  * @param rd_count number of records
+ * @param signature where to store the signature
+ */
+struct GNUNET_NAMESTORE_Block *
+GNUNET_NAMESTORE_block_create (const struct GNUNET_CRYPTO_EccPrivateKey *key,
+                              struct GNUNET_TIME_Absolute expire,
+                              const char *label,
+                              const struct GNUNET_NAMESTORE_RecordData *rd,
+                              unsigned int rd_count);
+
+
+/**
+ * Check if a signature is valid.  This API is used by the GNS Block
+ * to validate signatures received from the network.
  *
- * @return the signature
+ * @param block block to verify
+ * @return GNUNET_OK if the signature is valid
  */
-struct GNUNET_CRYPTO_EccSignature *
-GNUNET_NAMESTORE_create_signature (const struct GNUNET_CRYPTO_EccPrivateKey 
*key,
-                                  struct GNUNET_TIME_Absolute expire,
-                                  const char *name,
-                                  const struct GNUNET_NAMESTORE_RecordData *rd,
-                                  unsigned int rd_count);
+int
+GNUNET_NAMESTORE_block_verify (const struct GNUNET_NAMESTORE_Block *block);
 
 
 /**
+ * Decrypt block.
+ *
+ * @param block block to decrypt
+ * @param zone_key public key of the zone
+ * @param label the name for the records
+ * @param proc function to call with the result
+ * @param proc_cls closure for proc
+ * @param GNUNET_OK on success, GNUNET_SYSERR if the block was 
+ *        not well-formed
+ */
+int
+GNUNET_NAMESTORE_block_decrypt (const struct GNUNET_NAMESTORE_Block *block,
+                               const struct GNUNET_CRYPTO_EccPublicKey 
*zone_key,
+                               const char *label,
+                               GNUNET_NAMESTORE_RecordMonitor proc,
+                               void *proc_cls);
+
+
+/**
  * Compares if two records are equal
  *
  * @param a Record a

Modified: gnunet/src/include/gnunet_protocols.h
===================================================================
--- gnunet/src/include/gnunet_protocols.h       2013-08-12 18:00:43 UTC (rev 
28545)
+++ gnunet/src/include/gnunet_protocols.h       2013-08-12 19:09:52 UTC (rev 
28546)
@@ -1331,41 +1331,36 @@
  
******************************************************************************/
 
 /**
- * Client to service: register.
+ * Client to service: lookup block
  */
-#define GNUNET_MESSAGE_TYPE_NAMESTORE_START 430
+#define GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_BLOCK 431
 
 /**
- * Client to service: lookup name
+ * Service to client: result of block lookup
  */
-#define GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME 431
+#define GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_BLOCK_RESPONSE 432
 
 /**
- * Service to client: result of name lookup
+ * Client to service: store records (as authority)
  */
-#define GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPONSE 432
+#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE 433
 
 /**
- * Client to service: put records (for caching)
+ * Service to client: result of store operation.
  */
-#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT 433
+#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE 434
 
 /**
- * Service to client: result of put operation.
+ * Client to service: cache a block
  */
-#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT_RESPONSE 434
+#define GNUNET_MESSAGE_TYPE_NAMESTORE_BLOCK_CACHE 435
 
 /**
- * Client to service: create record as authority
+ * Service to client: result of block cache request
  */
-#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE 435
+#define GNUNET_MESSAGE_TYPE_NAMESTORE_BLOCK_CACHE_RESPONSE 436
 
 /**
- * Service to client: result of record creation request
- */
-#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE_RESPONSE 436
-
-/**
  * Client to service: "reverse" lookup for zone name based on zone key
  */
 #define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME 439
@@ -1387,6 +1382,11 @@
 #define GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_SYNC 442
 
 /**
+ * Service to client: here is a (plaintext) record you requested.
+ */
+#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT 443
+
+/**
  * Client to service: please start iteration; receives
  * "GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPONSE" messages in return.
  */

Modified: gnunet/src/namestore/Makefile.am
===================================================================
--- gnunet/src/namestore/Makefile.am    2013-08-12 18:00:43 UTC (rev 28545)
+++ gnunet/src/namestore/Makefile.am    2013-08-12 19:09:52 UTC (rev 28546)
@@ -25,12 +25,17 @@
 SQLITE_TESTS = test_plugin_namestore_sqlite 
 endif
 endif
+
 if HAVE_POSTGRES
+# postgres doesn't even build yet; thus: experimental!
+if HAVE_EXPERIMENTAL
 POSTGRES_PLUGIN = libgnunet_plugin_namestore_postgres.la
 if HAVE_TESTING
 POSTGRES_TESTS = test_plugin_namestore_postgres
 endif
 endif
+endif
+
 if HAVE_TESTING
 TESTING_TESTS = \
  test_namestore_api \

Modified: gnunet/src/namestore/gnunet-namestore.c
===================================================================
--- gnunet/src/namestore/gnunet-namestore.c     2013-08-12 18:00:43 UTC (rev 
28545)
+++ gnunet/src/namestore/gnunet-namestore.c     2013-08-12 19:09:52 UTC (rev 
28546)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     (C) 2012 Christian Grothoff (and other contributing authors)
+     (C) 2012, 2013 Christian Grothoff (and other contributing authors)
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
@@ -39,17 +39,12 @@
 static struct GNUNET_NAMESTORE_Handle *ns;
 
 /**
- * Hash of the public key of our zone.
- */
-static struct GNUNET_CRYPTO_ShortHashCode zone;
-
-/**
  * Private key for the our zone.
  */
 static struct GNUNET_CRYPTO_EccPrivateKey *zone_pkey;
 
 /**
- * Keyfile to manipulate.
+ * Keyfile to manipulate.  FIXME: change to ego's name!
  */
 static char *keyfile;  
 
@@ -59,9 +54,9 @@
 static int add;
 
 /**
- * Queue entry for the 'add' operation.
+ * Iterator for the 'add' operation.
  */
-static struct GNUNET_NAMESTORE_QueueEntry *add_qe;
+static struct GNUNET_NAMESTORE_ZoneIterator *add_zit;
 
 /**
  * Queue entry for the 'add-uri' operation.
@@ -69,6 +64,11 @@
 static struct GNUNET_NAMESTORE_QueueEntry *add_qe_uri;
 
 /**
+ * Queue entry for the 'add' operation.
+ */
+static struct GNUNET_NAMESTORE_QueueEntry *add_qe;
+
+/**
  * Desired action is to list records.
  */
 static int list;
@@ -168,6 +168,7 @@
  */
 static int monitor;
 
+
 /**
  * Task run on shutdown.  Cleans up everything.
  *
@@ -291,33 +292,21 @@
  * Process a record that was stored in the namestore.
  *
  * @param cls closure
- * @param zone_key public key of the zone
- * @param expire when does the corresponding block in the DHT expire (until
- *               when should we never do a DHT lookup for the same name 
again)?; 
- *               GNUNET_TIME_UNIT_ZERO_ABS if there are no records of any type 
in the namestore,
- *               or the expiration time of the block in the namestore (even if 
there are zero
- *               records matching the desired record type)
+ * @param zone_key private key of the zone
  * @param name name that is being mapped (at most 255 characters long)
  * @param rd_len number of entries in 'rd' array
  * @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)
  */
 static void
 display_record (void *cls,
-               const struct GNUNET_CRYPTO_EccPublicKey *zone_key,
-               struct GNUNET_TIME_Absolute expire,                         
+               const struct GNUNET_CRYPTO_EccPrivateKey *zone_key,
                const char *name,
                unsigned int rd_len,
-               const struct GNUNET_NAMESTORE_RecordData *rd,
-               const struct GNUNET_CRYPTO_EccSignature *signature)
+               const struct GNUNET_NAMESTORE_RecordData *rd)
 {
   const char *typestring;
   char *s;
   unsigned int i;
-  const char *etime;
-  struct GNUNET_TIME_Absolute aex;
-  struct GNUNET_TIME_Relative rex;
 
   if (NULL == name)
   {
@@ -343,21 +332,10 @@
               (unsigned int) rd[i].record_type);
       continue;
     }
-    if (0 != (rd[i].flags & GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION))
-    {
-      rex.rel_value_us = rd[i].expiration_time;
-      etime = GNUNET_STRINGS_relative_time_to_string (rex, GNUNET_YES);
-    }
-    else
-    {
-      aex.abs_value_us = rd[i].expiration_time;
-      etime = GNUNET_STRINGS_absolute_time_to_string (aex);
-    }
-    FPRINTF (stdout, "\t%s: %s (%s %s)\n", typestring, s, 
-            (0 != (rd[i].flags & GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION)) 
-            ? _(/* what follows is relative expiration */ "for at least")
-            : _(/* what follows is absolute expiration */ "until"),
-            etime);
+    FPRINTF (stdout, 
+            "\t%s: %s\n",
+            typestring, 
+            s);
     GNUNET_free (s);    
   }
   FPRINTF (stdout, "%s", "\n");
@@ -382,31 +360,27 @@
  * so that we can merge the information.
  *
  * @param cls closure, unused
- * @param zone_key public key of the zone
- * @param freshness when does the corresponding block in the DHT expire (until
- *               when should we never do a DHT lookup for the same name 
again)?; 
- *               GNUNET_TIME_UNIT_ZERO_ABS if there are no records of any type 
in the namestore,
- *               or the expiration time of the block in the namestore (even if 
there are zero
- *               records matching the desired record type)
+ * @param zone_key private key of the zone
  * @param rec_name name that is being mapped (at most 255 characters long)
  * @param rd_count number of entries in 'rd' array
  * @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)
  */
 static void
 get_existing_record (void *cls,
-                    const struct GNUNET_CRYPTO_EccPublicKey *zone_key,
-                    struct GNUNET_TIME_Absolute freshness,                     
    
+                    const struct GNUNET_CRYPTO_EccPrivateKey *zone_key,
                     const char *rec_name,
                     unsigned int rd_count,
-                    const struct GNUNET_NAMESTORE_RecordData *rd,
-                    const struct GNUNET_CRYPTO_EccSignature *signature)
+                    const struct GNUNET_NAMESTORE_RecordData *rd)
 {
   struct GNUNET_NAMESTORE_RecordData rdn[rd_count + 1];
   struct GNUNET_NAMESTORE_RecordData *rde;
-  
-  add_qe = NULL;
+
+  if ( (NULL != zone_key) &&
+       (0 != strcmp (rec_name, name)) )
+  {
+    GNUNET_NAMESTORE_zone_iterator_next (add_zit);
+    return;
+  }
   memset (rdn, 0, sizeof (struct GNUNET_NAMESTORE_RecordData));
   memcpy (&rdn[1], rd, rd_count * sizeof (struct GNUNET_NAMESTORE_RecordData));
   /* FIXME: should add some logic to overwrite records if there
@@ -416,27 +390,20 @@
   rde->data = data;
   rde->data_size = data_size;
   rde->record_type = type;
-  if (GNUNET_YES == etime_is_rel)
-  {
-    rde->expiration_time = etime_rel.rel_value_us;
-    rde->flags |= GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION;
-  }
-  else if (GNUNET_NO == etime_is_rel)
-  {
-    rde->expiration_time = etime_abs.abs_value_us;
-  }
   if (1 != nonauthority)
     rde->flags |= GNUNET_NAMESTORE_RF_AUTHORITY;
   if (1 != public)
     rde->flags |= GNUNET_NAMESTORE_RF_PRIVATE;
   GNUNET_assert (NULL != name);
-  add_qe = GNUNET_NAMESTORE_record_put_by_authority (ns,
-                                                    zone_pkey,
-                                                    name,
-                                                    rd_count + 1,
-                                                    rde,
-                                                    &add_continuation,
-                                                    &add_qe);
+  add_qe = GNUNET_NAMESTORE_records_store (ns,
+                                          zone_pkey,
+                                          name,
+                                          rd_count + 1,
+                                          rde,
+                                          &add_continuation,
+                                          &add_qe);
+  GNUNET_NAMESTORE_zone_iteration_stop (add_zit);
+  add_zit = NULL;
 }
 
 
@@ -494,7 +461,6 @@
   }
   GNUNET_CRYPTO_ecc_key_get_public (zone_pkey,
                                     &pub);
-  GNUNET_CRYPTO_short_hash (&pub, sizeof (pub), &zone);
 
   ns = GNUNET_NAMESTORE_connect (cfg);
   if (NULL == ns)
@@ -590,12 +556,10 @@
       ret = 1;
       return;     
     }
-    add_qe = GNUNET_NAMESTORE_lookup_record (ns,
-                                            &zone,
-                                            name,
-                                            0, 
-                                            &get_existing_record,
-                                            NULL);
+    add_zit = GNUNET_NAMESTORE_zone_iteration_start (ns,
+                                                    zone_pkey,
+                                                    &get_existing_record,
+                                                    NULL);
   }
   if (del)
   {
@@ -608,12 +572,12 @@
       ret = 1;
       return;     
     }
-    del_qe = GNUNET_NAMESTORE_record_put_by_authority (ns,
-                                                      zone_pkey,
-                                                      name,
-                                                      0, NULL,
-                                                      &del_continuation,
-                                                      NULL);
+    del_qe = GNUNET_NAMESTORE_records_store (ns,
+                                            zone_pkey,
+                                            name,
+                                            0, NULL,
+                                            &del_continuation,
+                                            NULL);
   }
   if (list)
   {
@@ -626,24 +590,22 @@
       must_not_flags |= GNUNET_NAMESTORE_RF_PRIVATE;
 
     list_it = GNUNET_NAMESTORE_zone_iteration_start (ns,
-                                                     &zone,
-                                                     
GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION,
-                                                     must_not_flags,
+                                                     zone_pkey,
                                                      &display_record,
                                                      NULL);
   }
   if (NULL != uri)
   {
-    char sh[53];
+    char sh[105];
     char sname[64];
-    struct GNUNET_CRYPTO_ShortHashCode sc;
+    struct GNUNET_CRYPTO_EccPublicKey pkey;
 
     if ( (2 != (sscanf (uri,
-                        "gnunet://gns/%52s/%63s",
+                        "gnunet://gns/%104s/%63s",
                         sh,
                         sname)) ) ||
          (GNUNET_OK !=
-          GNUNET_CRYPTO_short_hash_from_string (sh, &sc)) )
+          GNUNET_CRYPTO_ecc_public_key_from_string (sh, strlen (sh), &pkey)) )
     {
       fprintf (stderr, 
                _("Invalid URI `%s'\n"),
@@ -653,8 +615,8 @@
       return;
     }
     memset (&rd, 0, sizeof (rd));
-    rd.data = ≻
-    rd.data_size = sizeof (struct GNUNET_CRYPTO_ShortHashCode);
+    rd.data = &pkey;
+    rd.data_size = sizeof (struct GNUNET_CRYPTO_EccPublicKey);
     rd.record_type = GNUNET_NAMESTORE_TYPE_PKEY;
     if (GNUNET_YES == etime_is_rel)
     {
@@ -667,18 +629,18 @@
       rd.expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
     if (1 != nonauthority)
       rd.flags |= GNUNET_NAMESTORE_RF_AUTHORITY;
-    add_qe_uri = GNUNET_NAMESTORE_record_put_by_authority (ns,
-                                                          zone_pkey,
-                                                          sname,
-                                                          1,
-                                                          &rd,
-                                                          &add_continuation,
-                                                          &add_qe_uri);
+    add_qe_uri = GNUNET_NAMESTORE_records_store (ns,
+                                                zone_pkey,
+                                                sname,
+                                                1,
+                                                &rd,
+                                                &add_continuation,
+                                                &add_qe_uri);
   }
   if (monitor)
   {
     zm = GNUNET_NAMESTORE_zone_monitor_start (cfg,
-                                             &zone,
+                                             zone_pkey,
                                              &display_record,
                                              &sync_cb,
                                              NULL);

Modified: gnunet/src/namestore/namestore.h
===================================================================
--- gnunet/src/namestore/namestore.h    2013-08-12 18:00:43 UTC (rev 28545)
+++ gnunet/src/namestore/namestore.h    2013-08-12 19:09:52 UTC (rev 28546)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     (C) 2009 Christian Grothoff (and other contributing authors)
+     (C) 2011-2013 Christian Grothoff (and other contributing authors)
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
@@ -22,6 +22,7 @@
  * @file namestore/namestore.h
  * @brief common internal definitions for namestore service
  * @author Matthias Wachs
+ * @author Christian Grothoff
  */
 #ifndef NAMESTORE_H
 #define NAMESTORE_H
@@ -33,52 +34,7 @@
 
 GNUNET_NETWORK_STRUCT_BEGIN
 
-
 /**
- * A GNS record serialized for network transmission.
- *
- * Layout is [struct GNUNET_NAMESTORE_NetworkRecord][char[data_size] data]
- */
-struct GNUNET_NAMESTORE_NetworkRecord
-{
-  /**
-   * Expiration time for the DNS record.
-   */
-  struct GNUNET_TIME_AbsoluteNBO expiration;
-
-  /**
-   * Number of bytes in 'data'.
-   */
-  uint32_t data_size;
-
-  /**
-   * Type of the GNS/DNS record.
-   */
-  uint32_t record_type;
-
-  /**
-   * Flags for the record.
-   */
-  uint32_t flags;
-};
-
-
-
-/**
- * Connect to namestore service.  FIXME: UNNECESSARY.
- */
-struct StartMessage
-{
-
-  /**
-   * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_START
-   */
-  struct GNUNET_MessageHeader header;
-
-};
-
-
-/**
  * Generic namestore message with op id
  */
 struct GNUNET_NAMESTORE_Header
@@ -97,38 +53,30 @@
 
 
 /**
- * Lookup a name in the namestore
+ * Lookup a block in the namestore
  */
-struct LookupNameMessage
+struct LookupBlockMessage
 {
-  struct GNUNET_NAMESTORE_Header gns_header;
-
   /**
-   * The zone 
+   * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_BLOCK
    */
-  struct GNUNET_CRYPTO_ShortHashCode zone;
+  struct GNUNET_NAMESTORE_Header gns_header;
 
   /**
-   * Requested record type 
+   * The query.
    */
-  uint32_t record_type;
+  struct GNUNET_HashCode query;
 
-  /**
-   * Length of the name
-   */
-  uint32_t name_len;
-
-  /* 0-terminated name here */
 };
 
 
 /**
  * Lookup response
  */
-struct LookupNameResponseMessage
+struct LookupBlockResponseMessage
 {
   /**
-   * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPONSE
+   * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_BLOCK_RESPONSE
    */
   struct GNUNET_NAMESTORE_Header gns_header;
 
@@ -138,48 +86,26 @@
   struct GNUNET_TIME_AbsoluteNBO expire;
 
   /**
-   * Name length
+   * Signature.
    */
-  uint16_t name_len;
-
-  /**
-   * Bytes of serialized record data
-   */
-  uint16_t rd_len;
-
-  /**
-   * Number of records contained
-   */
-  uint16_t rd_count;
-
-  /**
-   * Is the signature valid
-   * GNUNET_YES or GNUNET_NO
-   */
-  int16_t contains_sig;
-
-  /**
-   * All zeros if 'contains_sig' is GNUNET_NO.
-   */
   struct GNUNET_CRYPTO_EccSignature signature;
 
   /**
-   * The public key for the name
+   * Derived public key.
    */
-  struct GNUNET_CRYPTO_EccPublicKey public_key;
+  struct GNUNET_CRYPTO_EccPublicKey derived_key;
 
-  /* 0-terminated name and serialized record data */
-  /* rd_len bytes serialized record data */
+  /* follwed by encrypted block data */
 };
 
 
 /**
- * Put a record to the namestore
+ * Cache a record in the namestore.
  */
-struct RecordPutMessage
+struct BlockCacheMessage
 {
   /**
-   * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_RECORD_PUT
+   * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_BLOCK_CACHE
    */
   struct GNUNET_NAMESTORE_Header gns_header;
 
@@ -189,70 +115,49 @@
   struct GNUNET_TIME_AbsoluteNBO expire;
 
   /**
-   * Name length
+   * Signature.
    */
-  uint16_t name_len;
-
-  /**
-   * Length of serialized record data
-   */
-  uint16_t rd_len;
-
-  /**
-   * Number of records contained 
-   */
-  uint16_t rd_count;
-
-  /**
-   * always zero (for alignment)
-   */
-  uint16_t reserved;
-
-  /**
-   * The signature
-   */
   struct GNUNET_CRYPTO_EccSignature signature;
 
   /**
-   * The public key
+   * Derived public key.
    */
-  struct GNUNET_CRYPTO_EccPublicKey public_key;
+  struct GNUNET_CRYPTO_EccPublicKey derived_key;
 
-  /* name (0-terminated) followed by "rd_count" serialized records */
-
+  /* follwed by encrypted block data */
 };
 
 
 /**
- * Put a record to the namestore response
+ * Response to a request to cache a block.
  */
-struct RecordPutResponseMessage
+struct BlockCacheResponseMessage
 {
   /**
-   * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT_RESPONSE
+   * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_BLOCK_CACHE_RESPONSE
    */
   struct GNUNET_NAMESTORE_Header gns_header;
 
   /**
-   * result:
-   * GNUNET_SYSERR on failure
-   * GNUNET_OK on success
+   *  name length: GNUNET_NO already exists, GNUNET_YES on success, 
GNUNET_SYSERR error
    */
   int32_t op_result;
 };
 
 
 /**
- * Create a record and put it to the namestore
- * Memory layout:
+ * Store a record to the namestore (as authority).
  */
-struct RecordCreateMessage
+struct RecordStoreMessage
 {
   /**
-   * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE
+   * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_RECORD_STORE
    */
   struct GNUNET_NAMESTORE_Header gns_header;
 
+  /**
+   * Expiration time
+   */
   struct GNUNET_TIME_AbsoluteNBO expire;
 
   /**
@@ -266,41 +171,47 @@
   uint16_t rd_len;
 
   /**
-   * Record count 
+   * Number of records contained 
    */
   uint16_t rd_count;
 
   /**
-   * always zero
+   * always zero (for alignment)
    */
   uint16_t reserved;
 
+  /**
+   * The private key of the authority.
+   */
   struct GNUNET_CRYPTO_EccPrivateKey private_key;
 
   /* followed by:
    * name with length name_len
-   * serialized record data with length rd_len
+   * serialized record data with rd_count records
    */
 };
 
 
 /**
- * Create a record to the namestore response
+ * Response to a record storage request.
  */
-struct RecordCreateResponseMessage
+struct RecordStoreResponseMessage
 {
   /**
-   * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE_RESPONSE
+   * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE
    */
   struct GNUNET_NAMESTORE_Header gns_header;
 
   /**
-   *  name length: GNUNET_NO already exists, GNUNET_YES on success, 
GNUNET_SYSERR error
+   * result:
+   * GNUNET_SYSERR on failure
+   * GNUNET_OK on success
    */
   int32_t op_result;
 };
 
 
+
 /**
  * Lookup a name for a zone hash
  */
@@ -312,14 +223,14 @@
   struct GNUNET_NAMESTORE_Header gns_header;
 
   /**
-   * The hash of public key of the zone to look up in 
+   * The private key of the zone to look up in 
    */
-  struct GNUNET_CRYPTO_ShortHashCode zone;
+  struct GNUNET_CRYPTO_EccPrivateKey zone;
 
   /**
-   * The  hash of the public key of the target zone  
+   * The public key of the target zone  
    */
-  struct GNUNET_CRYPTO_ShortHashCode value_zone;
+  struct GNUNET_CRYPTO_EccPublicKey value_zone;
 };
 
 
@@ -334,11 +245,6 @@
   struct GNUNET_NAMESTORE_Header gns_header;
 
   /**
-   * Record block expiration
-   */
-  struct GNUNET_TIME_AbsoluteNBO expire;
-
-  /**
    * Length of the name
    */
   uint16_t name_len;
@@ -360,66 +266,93 @@
   int16_t res;
 
   /**
-   * Signature
+   * The private key of the zone that contained the name.
    */
-  struct GNUNET_CRYPTO_EccSignature signature;
+  struct GNUNET_CRYPTO_EccPrivateKey zone;
 
-  /**
-   * Publik key
+  /* followed by:
+   * name with length name_len
+   * serialized record data with rd_count records
    */
-  struct GNUNET_CRYPTO_EccPublicKey zone_key;
 
 };
 
 
 /**
- * Start monitoring a zone.
+ * Record is returned from the namestore (as authority).
  */
-struct ZoneMonitorStartMessage
+struct RecordResultMessage
 {
   /**
-   * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_START
+   * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT
    */
   struct GNUNET_NAMESTORE_Header gns_header;
 
   /**
-   * Zone hash
+   * Name length
    */
-  struct GNUNET_CRYPTO_ShortHashCode zone;
+  uint16_t name_len;
 
   /**
-   * All zones. GNUNET_YES to monitor all zones,
-   * GNUNET_NO to only monitor 'zone'.  In NBO.
+   * Length of serialized record data
    */
-  uint32_t all_zones GNUNET_PACKED;
+  uint16_t rd_len;
 
+  /**
+   * Number of records contained 
+   */
+  uint16_t rd_count;
+
+  /**
+   * always zero (for alignment)
+   */
+  uint16_t reserved;
+
+  /**
+   * The private key of the authority.
+   */
+  struct GNUNET_CRYPTO_EccPrivateKey private_key;
+
+  /* followed by:
+   * name with length name_len
+   * serialized record data with rd_count records
+   */
 };
 
 
 /**
- * Start a zone iteration for the given zone
+ * Start monitoring a zone.
  */
-struct ZoneIterationStartMessage
+struct ZoneMonitorStartMessage
 {
   /**
-   * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START
+   * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_START
    */
   struct GNUNET_NAMESTORE_Header gns_header;
 
   /**
-   * Zone hash
+   * Zone key.
    */
-  struct GNUNET_CRYPTO_ShortHashCode zone;
+  struct GNUNET_CRYPTO_EccPrivateKey zone;
 
+};
+
+
+/**
+ * Start a zone iteration for the given zone
+ */
+struct ZoneIterationStartMessage
+{
   /**
-   * Which flags must be included
+   * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START
    */
-  uint16_t must_have_flags;
+  struct GNUNET_NAMESTORE_Header gns_header;
 
   /**
-   * Which flags must not be included
+   * Zone key.
    */
-  uint16_t must_not_have_flags;
+  struct GNUNET_CRYPTO_EccPrivateKey zone;
+
 };
 
 

Modified: gnunet/src/namestore/namestore_api.c
===================================================================
--- gnunet/src/namestore/namestore_api.c        2013-08-12 18:00:43 UTC (rev 
28545)
+++ gnunet/src/namestore/namestore_api.c        2013-08-12 19:09:52 UTC (rev 
28546)
@@ -75,7 +75,7 @@
   /**
    * Function to call with the records we get back; or NULL.
    */
-  GNUNET_NAMESTORE_RecordProcessor proc;
+  GNUNET_NAMESTORE_RecordMonitor proc;
 
   /**
    * Closure for 'proc'.
@@ -83,6 +83,16 @@
   void *proc_cls;
 
   /**
+   * Function to call with the blocks we get back; or NULL.
+   */
+  GNUNET_NAMESTORE_BlockProcessor block_proc;
+
+  /**
+   * Closure for 'block_proc'.
+   */
+  void *block_proc_cls;
+
+  /**
    * The operation id this zone iteration operation has
    */
   uint32_t op_id;
@@ -114,7 +124,7 @@
   /**
    * The continuation to call with the results
    */
-  GNUNET_NAMESTORE_RecordProcessor proc;
+  GNUNET_NAMESTORE_RecordMonitor proc;
 
   /**
    * Closure for 'proc'.
@@ -122,23 +132,15 @@
   void* proc_cls;
 
   /**
-   * If this iterator iterates over a specific zone this value contains the
-   * short hash of the zone
+   * Private key of the zone.
    */
-  struct GNUNET_CRYPTO_ShortHashCode zone;
+  struct GNUNET_CRYPTO_EccPrivateKey zone;
 
   /**
    * The operation id this zone iteration operation has
    */
   uint32_t op_id;
 
-  /**
-   * GNUNET_YES if this iterator iterates over a specific zone
-   * GNUNET_NO if this iterator iterates over all zones
-   *
-   * Zone is stored GNUNET_CRYPTO_ShortHashCode 'zone';
-   */
-  int has_zone;
 };
 
 
@@ -164,10 +166,6 @@
    */
   size_t size;
 
-  /**
-   * Is this the 'START' message?
-   */
-  int is_init;
 };
 
 
@@ -233,6 +231,11 @@
   int reconnect;
 
   /**
+   * Did we start to receive yet?
+   */
+  int is_receiving;
+
+  /**
    * The last operation id used for a NAMESTORE operation
    */
   uint32_t last_op_id_used;
@@ -250,7 +253,7 @@
 
 
 /**
- * Handle an incoming message of type 
'GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPONSE'
+ * Handle an incoming message of type 
'GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_BLOCK_RESPONSE'
  *
  * @param qe the respective entry in the message queue
  * @param msg the message we received
@@ -258,73 +261,41 @@
  * @return GNUNET_OK on success, GNUNET_SYSERR on error and we did NOT notify 
the client
  */
 static int
-handle_lookup_name_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
-                             const struct LookupNameResponseMessage * msg,
-                             size_t size)
+handle_lookup_block_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
+                             const struct LookupBlockResponseMessage *msg,
+                             size_t size)
 {
-  const char *name;
-  const char * rd_tmp;
-  const struct GNUNET_CRYPTO_EccSignature *signature;
-  struct GNUNET_TIME_Absolute expire;
-  const struct GNUNET_CRYPTO_EccPublicKey *public_key_tmp;
-  size_t exp_msg_len;
-  size_t msg_len;
-  size_t name_len;
-  size_t rd_len;
-  int contains_sig;
-  int rd_count;
+  struct GNUNET_NAMESTORE_Block *block;
+  char buf[size + sizeof (struct GNUNET_NAMESTORE_Block) - sizeof (struct 
LookupBlockResponseMessage)];
 
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Received `%s'\n", 
-       "LOOKUP_NAME_RESPONSE");
-  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);
-  contains_sig = ntohs (msg->contains_sig);
-  expire = GNUNET_TIME_absolute_ntoh (msg->expire);
-  exp_msg_len = sizeof (struct LookupNameResponseMessage) +
-      name_len + rd_len;
-  if (msg_len != exp_msg_len)
+       "LOOKUP_BLOCK_RESPONSE");
+  block = (struct GNUNET_NAMESTORE_Block *) buf;
+  block->signature = msg->signature;
+  block->derived_key = msg->derived_key;
+  block->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
+  block->purpose.size = htonl (size - sizeof (struct 
LookupBlockResponseMessage) + sizeof (struct GNUNET_TIME_AbsoluteNBO));
+  block->expiration_time = msg->expire;
+  memcpy (&block[1],
+         &msg[1],
+         size - sizeof (struct LookupBlockResponseMessage));
+  if (GNUNET_OK !=
+      GNUNET_NAMESTORE_block_verify (block))
   {
     GNUNET_break (0);
     return GNUNET_SYSERR;
   }
-  name = (const char *) &msg[1];
-  if ( (name_len > 0) &&
-       ('\0' != name[name_len -1]) )
-  {
+  if (NULL != qe->block_proc)
+    qe->block_proc (qe->proc_cls, block);  
+  else
     GNUNET_break (0);
-    return GNUNET_SYSERR;
-  }
-  rd_tmp = &name[name_len];
-  {
-    struct GNUNET_NAMESTORE_RecordData rd[rd_count];
-
-    if (GNUNET_OK != GNUNET_NAMESTORE_records_deserialize(rd_len, rd_tmp, 
rd_count, rd))
-    {
-      GNUNET_break (0);
-      return GNUNET_SYSERR;
-    }
-    if (GNUNET_NO == contains_sig)
-      signature = NULL;
-    else
-      signature = &msg->signature;
-    if (0 == name_len)
-      name = NULL;
-    if (NULL != name)
-      public_key_tmp = &msg->public_key;
-    else
-      public_key_tmp = NULL;    
-    if (NULL != qe->proc)
-      qe->proc (qe->proc_cls, public_key_tmp, expire, name, rd_count, 
(rd_count > 0) ? rd : NULL, signature);      
-  }
   return GNUNET_OK;
 }
 
 
 /**
- * Handle an incoming message of type 
'GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT_RESPONSE'
+ * Handle an incoming message of type 
'GNUNET_MESSAGE_TYPE_NAMESTORE_BLOCK_CACHE_RESPONSE'
  *
  * @param qe the respective entry in the message queue
  * @param msg the message we received
@@ -332,24 +303,24 @@
  * @return GNUNET_OK on success, GNUNET_SYSERR on error and we did NOT notify 
the client
  */
 static int
-handle_record_put_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
-                           const struct RecordPutResponseMessage* msg,
+handle_block_cache_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
+                           const struct BlockCacheResponseMessage *msg,
                            size_t size)
 {
   int res;
 
   LOG (GNUNET_ERROR_TYPE_DEBUG, "Received `%s'\n",
-       "RECORD_PUT_RESPONSE");
+       "BLOCK_CACHE_RESPONSE");
   res = ntohl (msg->op_result);
   /* TODO: add actual error message from namestore to response... */
   if (NULL != qe->cont)    
-    qe->cont (qe->cont_cls, res, (GNUNET_OK == res) ? NULL : _("Namestore 
failed to add record"));
+    qe->cont (qe->cont_cls, res, (GNUNET_OK == res) ? NULL : _("Namestore 
failed to cache block"));
   return GNUNET_OK;
 }
 
 
 /**
- * Handle an incoming message of type 
'GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE_RESPONSE'
+ * Handle an incoming message of type 
'GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE'
  *
  * @param qe the respective entry in the message queue
  * @param msg the message we received
@@ -357,19 +328,19 @@
  * @return GNUNET_OK on success, GNUNET_SYSERR on error and we did NOT notify 
the client
  */
 static int
-handle_record_create_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
-                              const struct RecordCreateResponseMessage* msg,
-                              size_t size)
+handle_record_store_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
+                             const struct RecordStoreResponseMessage* msg,
+                             size_t size)
 {
   int res;
   const char *emsg;
   
   LOG (GNUNET_ERROR_TYPE_DEBUG, "Received `%s'\n",
-       "RECORD_CREATE_RESPONSE");
+       "RECORD_STORE_RESPONSE");
   /* TODO: add actual error message from namestore to response... */
   res = ntohl (msg->op_result);
   if (GNUNET_SYSERR == res)
-    emsg = _("Namestore failed to add record\n");
+    emsg = _("Namestore failed to store record\n");
   else
     emsg = NULL;
   if (NULL != qe->cont)    
@@ -379,6 +350,70 @@
 
 
 /**
+ * Handle an incoming message of type 
'GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT'
+ *
+ * @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_record_result (struct GNUNET_NAMESTORE_QueueEntry *qe,
+                     const struct RecordResultMessage *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;
+
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Received `%s'\n", 
+       "RECORD_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);
+  GNUNET_break (0 == ntohs (msg->reserved));
+  exp_msg_len = sizeof (struct RecordResultMessage) + 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;
+  }
+  rd_tmp = &name[name_len];
+  {
+    struct GNUNET_NAMESTORE_RecordData rd[rd_count];
+
+    if (GNUNET_OK != GNUNET_NAMESTORE_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_ZONE_TO_NAME_RESPONSE'
  *
  * @param qe the respective entry in the message queue
@@ -389,16 +424,15 @@
  */
 static int
 handle_zone_to_name_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
-                             const struct ZoneToNameResponseMessage* msg,
+                             const struct ZoneToNameResponseMessage *msg,
                              size_t size)
 {
   int res;
-  struct GNUNET_TIME_Absolute expire;
   size_t name_len;
   size_t rd_ser_len;
   unsigned int rd_count;
-  const char * name_tmp;
-  const char * rd_tmp;
+  const char *name_tmp;
+  const char *rd_tmp;
 
   LOG (GNUNET_ERROR_TYPE_DEBUG, 
        "Received `%s'\n",
@@ -417,7 +451,6 @@
     name_len = ntohs (msg->name_len);
     rd_count = ntohs (msg->rd_count);
     rd_ser_len = ntohs (msg->rd_len);
-    expire = GNUNET_TIME_absolute_ntoh(msg->expire);
     name_tmp = (const char *) &msg[1];
     if ( (name_len > 0) &&
         ('\0' != name_tmp[name_len -1]) )
@@ -435,7 +468,10 @@
       }
       /* normal end, call continuation with result */
       if (NULL != qe->proc)
-       qe->proc (qe->proc_cls, &msg->zone_key, expire, name_tmp, rd_count, rd, 
&msg->signature);           
+       qe->proc (qe->proc_cls, 
+                 &msg->zone,
+                 name_tmp, 
+                 rd_count, rd);           
       /* return is important here: break would call continuation with error! */
       return GNUNET_OK;
     }
@@ -445,7 +481,7 @@
   }
   /* error case, call continuation with error */
   if (NULL != qe->proc)
-    qe->proc (qe->proc_cls, NULL, GNUNET_TIME_UNIT_ZERO_ABS, NULL, 0, NULL, 
NULL);
+    qe->proc (qe->proc_cls, NULL, NULL, 0, NULL);
   return GNUNET_OK;
 }
 
@@ -469,27 +505,27 @@
   /* handle different message type */
   switch (type) 
   {
-  case GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPONSE:
-    if (size < sizeof (struct LookupNameResponseMessage))
+  case GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_BLOCK_RESPONSE:
+    if (size < sizeof (struct LookupBlockResponseMessage))
     {
       GNUNET_break (0);
       return GNUNET_SYSERR;
     }
-    return handle_lookup_name_response (qe, (const struct 
LookupNameResponseMessage *) msg, size);
-  case GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT_RESPONSE:
-    if (size != sizeof (struct RecordPutResponseMessage))
+    return handle_lookup_block_response (qe, (const struct 
LookupBlockResponseMessage *) msg, size);
+  case GNUNET_MESSAGE_TYPE_NAMESTORE_BLOCK_CACHE_RESPONSE:
+    if (size != sizeof (struct BlockCacheResponseMessage))
     {
       GNUNET_break (0);
       return GNUNET_SYSERR;
     }
-    return handle_record_put_response (qe, (const struct 
RecordPutResponseMessage *) msg, size);
-  case GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE_RESPONSE:
-    if (size != sizeof (struct RecordCreateResponseMessage))
+    return handle_block_cache_response (qe, (const struct 
BlockCacheResponseMessage *) msg, size);
+  case GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE:
+    if (size != sizeof (struct RecordStoreResponseMessage))
     {
       GNUNET_break (0);
       return GNUNET_SYSERR;
     }
-    return handle_record_create_response (qe, (const struct 
RecordCreateResponseMessage *) msg, size);
+    return handle_record_store_response (qe, (const struct 
RecordStoreResponseMessage *) msg, size);
   case GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE:
     if (size < sizeof (struct ZoneToNameResponseMessage))
     {
@@ -497,6 +533,13 @@
       return GNUNET_SYSERR;
     }
     return handle_zone_to_name_response (qe, (const struct 
ZoneToNameResponseMessage *) msg, size);
+  case GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT:
+    if (size < sizeof (struct RecordResultMessage))
+    {
+      GNUNET_break (0);
+      return GNUNET_SYSERR;
+    }
+    return handle_record_result (qe, (const struct RecordResultMessage *) msg, 
size);
   default:
     GNUNET_break (0);
     return GNUNET_SYSERR;
@@ -515,10 +558,10 @@
  */
 static int
 handle_zone_iteration_response (struct GNUNET_NAMESTORE_ZoneIterator *ze,
-                                const struct LookupNameResponseMessage *msg,
+                                const struct RecordResultMessage *msg,
                                 size_t size)
 {
-  struct GNUNET_CRYPTO_EccPublicKey pubdummy;
+  static struct GNUNET_CRYPTO_EccPrivateKey priv_dummy;
   size_t msg_len;
   size_t exp_msg_len;
   size_t name_len;
@@ -526,27 +569,25 @@
   unsigned rd_count;
   const char *name_tmp;
   const char *rd_ser_tmp;
-  struct GNUNET_TIME_Absolute expire;
 
-  LOG (GNUNET_ERROR_TYPE_DEBUG, "Received `%s'\n",
+  LOG (GNUNET_ERROR_TYPE_DEBUG, 
+       "Received `%s'\n",
        "ZONE_ITERATION_RESPONSE");
   msg_len = ntohs (msg->gns_header.header.size);
   rd_len = ntohs (msg->rd_len);
   rd_count = ntohs (msg->rd_count);
   name_len = ntohs (msg->name_len);
-  expire = GNUNET_TIME_absolute_ntoh (msg->expire);
-  exp_msg_len = sizeof (struct LookupNameResponseMessage) + name_len + rd_len;
+  exp_msg_len = sizeof (struct RecordResultMessage) + name_len + rd_len;
   if (msg_len != exp_msg_len)
   {
     GNUNET_break (0);
     return GNUNET_SYSERR;
   }
-  memset (&pubdummy, '\0', sizeof (pubdummy));
-  if ((0 == name_len) && (0 == (memcmp (&msg->public_key, &pubdummy, sizeof 
(pubdummy)))))
+  if ((0 == name_len) && (0 == (memcmp (&msg->private_key, &priv_dummy, sizeof 
(priv_dummy)))))
   {
     LOG (GNUNET_ERROR_TYPE_DEBUG, "Zone iteration is completed!\n");
     if (NULL != ze->proc)
-      ze->proc(ze->proc_cls, NULL, GNUNET_TIME_UNIT_ZERO_ABS, NULL , 0, NULL, 
NULL);
+      ze->proc (ze->proc_cls, NULL, NULL, 0, NULL);
     return GNUNET_NO;
   }
   name_tmp = (const char *) &msg[1];
@@ -565,7 +606,7 @@
       return GNUNET_SYSERR;
     }
     if (NULL != ze->proc)
-      ze->proc(ze->proc_cls, &msg->public_key, expire, name_tmp, rd_count, rd, 
&msg->signature);
+      ze->proc (ze->proc_cls, &msg->private_key, name_tmp, rd_count, rd);
     return GNUNET_YES;
   }
 }
@@ -589,13 +630,13 @@
   /* handle different message type */
   switch (type) 
   {
-  case GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPONSE:
-    if (size < sizeof (struct LookupNameResponseMessage))
+  case GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT:
+    if (size < sizeof (struct RecordResultMessage))
     {
       GNUNET_break (0);
       return GNUNET_SYSERR;
     }
-    return handle_zone_iteration_response (ze, (const struct 
LookupNameResponseMessage *) msg, size);
+    return handle_zone_iteration_response (ze, (const struct 
RecordResultMessage *) msg, size);
   default:
     GNUNET_break (0);
     return GNUNET_SYSERR;
@@ -611,7 +652,8 @@
  * @param msg message received, NULL on timeout or fatal error
  */
 static void
-process_namestore_message (void *cls, const struct GNUNET_MessageHeader *msg)
+process_namestore_message (void *cls, 
+                          const struct GNUNET_MessageHeader *msg)
 {
   struct GNUNET_NAMESTORE_Handle *h = cls;
   const struct GNUNET_NAMESTORE_Header *gm;
@@ -639,7 +681,8 @@
   gm = (const struct GNUNET_NAMESTORE_Header *) msg;
   r_id = ntohl (gm->r_id);
 
-  LOG (GNUNET_ERROR_TYPE_DEBUG, "Received message type %u size %u op %u\n", 
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Received message type %u size %u op %u\n", 
        (unsigned int) type,
        (unsigned int) size, 
        (unsigned int) r_id);
@@ -737,9 +780,13 @@
     ret += p->size;
     size -= p->size;
     GNUNET_CONTAINER_DLL_remove (h->pending_head, h->pending_tail, p);
-    if (GNUNET_YES == p->is_init)
-      GNUNET_CLIENT_receive (h->client, &process_namestore_message, h,
+    if (GNUNET_NO == h->is_receiving)
+    {
+      h->is_receiving = GNUNET_YES;
+      GNUNET_CLIENT_receive (h->client,
+                            &process_namestore_message, h,
                              GNUNET_TIME_UNIT_FOREVER_REL);
+    }
     GNUNET_free (p);
   }
   do_transmit (h);
@@ -779,23 +826,9 @@
 static void
 reconnect (struct GNUNET_NAMESTORE_Handle *h)
 {
-  struct PendingMessage *p;
-  struct StartMessage *init;
-
   GNUNET_assert (NULL == h->client);
   h->client = GNUNET_CLIENT_connect ("namestore", h->cfg);
   GNUNET_assert (NULL != h->client);
-  if ((NULL == (p = h->pending_head)) || (GNUNET_YES != p->is_init))
-  {
-    p = GNUNET_malloc (sizeof (struct PendingMessage) +
-                       sizeof (struct StartMessage));
-    p->size = sizeof (struct StartMessage);
-    p->is_init = GNUNET_YES;
-    init = (struct StartMessage *) &p[1];
-    init->header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_START);
-    init->header.size = htons (sizeof (struct StartMessage));
-    GNUNET_CONTAINER_DLL_insert (h->pending_head, h->pending_tail, p);
-  }
   do_transmit (h);
 }
 
@@ -826,6 +859,7 @@
 {
   h->reconnect = GNUNET_NO;
   GNUNET_CLIENT_disconnect (h->client);
+  h->is_receiving = GNUNET_NO;
   h->client = NULL;
   h->reconnect_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
                                                    &reconnect_task,
@@ -857,7 +891,7 @@
 {
   struct GNUNET_NAMESTORE_Handle *h;
 
-  h = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_Handle));
+  h = GNUNET_new (struct GNUNET_NAMESTORE_Handle);
   h->cfg = cfg;
   h->reconnect_task = GNUNET_SCHEDULER_add_now (&reconnect_task, h);
   h->last_op_id_used = 0;
@@ -913,60 +947,31 @@
 
 /**
  * Store an item in the namestore.  If the item is already present,
- * the expiration time is updated to the max of the existing time and
- * the new time.  This API is used when we cache signatures from other
- * authorities.
+ * it is replaced with the new record.  
  *
  * @param h handle to the namestore
- * @param zone_key public key of the zone
- * @param name name that is being mapped (at most 255 characters long)
- * @param freshness when does the corresponding block in the DHT expire (until
- *               when should we never do a DHT lookup for the same name again)?
- * @param rd_count number of entries in 'rd' array
- * @param rd array of records with data to store
- * @param signature signature for all the records in the zone under the given 
name
+ * @param block block to store
  * @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_record_put (struct GNUNET_NAMESTORE_Handle *h,
-                            const struct GNUNET_CRYPTO_EccPublicKey *zone_key,
-                            const char *name,
-                            struct GNUNET_TIME_Absolute freshness,
-                            unsigned int rd_count,
-                            const struct GNUNET_NAMESTORE_RecordData *rd,
-                            const struct GNUNET_CRYPTO_EccSignature *signature,
-                            GNUNET_NAMESTORE_ContinuationWithStatus cont,
-                            void *cont_cls)
+GNUNET_NAMESTORE_block_cache (struct GNUNET_NAMESTORE_Handle *h,
+                             const struct GNUNET_NAMESTORE_Block *block,
+                             GNUNET_NAMESTORE_ContinuationWithStatus cont,
+                             void *cont_cls)
 {
   struct GNUNET_NAMESTORE_QueueEntry *qe;
   struct PendingMessage *pe;
-  struct RecordPutMessage * msg;
-  char * rd_ser;
-  char * name_tmp;
+  struct BlockCacheMessage *msg;
+  uint32_t rid;
+  size_t blen;
   size_t msg_size;
-  size_t name_len;
-  size_t rd_ser_len;
-  uint32_t rid;
 
   GNUNET_assert (NULL != h);
-  GNUNET_assert (NULL != zone_key);
-  GNUNET_assert (NULL != name);
-  GNUNET_assert (NULL != rd);
-  GNUNET_assert (NULL != signature);
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Storing %u records under name `%s'\n",
-       rd_count,
-       name);
-  name_len = strlen(name) + 1;
-  if (name_len > MAX_NAME_LEN)
-  {
-    GNUNET_break (0);
-    return NULL;
-  }
+  blen = ntohl (block->purpose.size) - sizeof (struct GNUNET_TIME_AbsoluteNBO);
   rid = get_op_id (h);
-  qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry));
+  qe = GNUNET_new (struct GNUNET_NAMESTORE_QueueEntry);
   qe->nsh = h;
   qe->cont = cont;
   qe->cont_cls = cont_cls;
@@ -974,29 +979,21 @@
   GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, qe);
 
   /* setup msg */
-  rd_ser_len = GNUNET_NAMESTORE_records_get_size(rd_count, rd);
-  msg_size = sizeof (struct RecordPutMessage) + name_len  + rd_ser_len;
-  pe = GNUNET_malloc(sizeof (struct PendingMessage) + msg_size);
+  msg_size = sizeof (struct BlockCacheMessage) + blen;
+  pe = GNUNET_malloc (sizeof (struct PendingMessage) + msg_size);
   pe->size = msg_size;
-  pe->is_init = GNUNET_NO;
-  msg = (struct RecordPutMessage *) &pe[1];
-  msg->gns_header.header.type = htons 
(GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT);
+  msg = (struct BlockCacheMessage *) &pe[1];
+  msg->gns_header.header.type = htons 
(GNUNET_MESSAGE_TYPE_NAMESTORE_BLOCK_CACHE);
   msg->gns_header.header.size = htons (msg_size);
   msg->gns_header.r_id = htonl (rid);
-  msg->signature = *signature;
-  msg->name_len = htons (name_len);
-  msg->expire = GNUNET_TIME_absolute_hton (freshness);
-  msg->rd_len = htons (rd_ser_len);
-  msg->rd_count = htons (rd_count);
-  msg->public_key = *zone_key;
-  name_tmp = (char *) &msg[1];
-  memcpy (name_tmp, name, name_len);
-  rd_ser = &name_tmp[name_len];
-  GNUNET_break (rd_ser_len == GNUNET_NAMESTORE_records_serialize (rd_count, 
rd, rd_ser_len, rd_ser));
+  msg->expire = block->expiration_time;
+  msg->signature = block->signature;
+  msg->derived_key = block->derived_key;
+  memcpy (&msg[1], &block[1], blen);
   LOG (GNUNET_ERROR_TYPE_DEBUG, 
-       "Sending `%s' message for name `%s' with size %u\n", 
-       "NAMESTORE_RECORD_PUT", 
-       name, msg_size);
+       "Sending `%s' message with size %u\n", 
+       "NAMESTORE_BLOCK_CACHE", 
+       (unsigned int) msg_size);
   GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
   do_transmit(h);
   return qe;
@@ -1004,86 +1001,27 @@
 
 
 /**
- * Check if a signature is valid.  This API is used by the GNS Block
- * to validate signatures received from the network.
- *
- * @param public_key public key of the zone
- * @param freshness block expiration
- * @param name name that is being mapped (at most 255 characters long)
- * @param rd_count number of entries in 'rd' array
- * @param rd array of records with data to store
- * @param signature signature for all the records in the zone under the given 
name
- * @return GNUNET_OK if the signature is valid
- */
-int
-GNUNET_NAMESTORE_verify_signature (const struct GNUNET_CRYPTO_EccPublicKey 
*public_key,
-                                   const struct GNUNET_TIME_Absolute freshness,
-                                  const char *name,
-                                  unsigned int rd_count,
-                                  const struct GNUNET_NAMESTORE_RecordData *rd,
-                                  const struct GNUNET_CRYPTO_EccSignature 
*signature)
-{
-  size_t rd_ser_len;
-  size_t name_len;
-  char *name_tmp;
-  char *rd_ser;
-  struct GNUNET_CRYPTO_EccSignaturePurpose *sig_purpose;
-  struct GNUNET_TIME_AbsoluteNBO *expire_tmp;
-  struct GNUNET_TIME_AbsoluteNBO expire_nbo = GNUNET_TIME_absolute_hton 
(freshness);
-  uint32_t sig_len;
-
-  GNUNET_assert (NULL != public_key);
-  GNUNET_assert (NULL != name);
-  GNUNET_assert (NULL != rd);
-  GNUNET_assert (NULL != signature);
-  name_len = strlen (name) + 1;
-  if (name_len > MAX_NAME_LEN)
-  {
-    GNUNET_break (0);
-    return GNUNET_SYSERR;
-  }
-  rd_ser_len = GNUNET_NAMESTORE_records_get_size (rd_count, rd);
-  sig_len = sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + sizeof (struct 
GNUNET_TIME_AbsoluteNBO) + rd_ser_len + name_len;
-  {
-    char sig_buf[sig_len] GNUNET_ALIGN;
-
-    sig_purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose *) sig_buf;
-    sig_purpose->size = htonl (sig_len);
-    sig_purpose->purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
-    expire_tmp = (struct GNUNET_TIME_AbsoluteNBO *) &sig_purpose[1];
-    memcpy (expire_tmp, &expire_nbo, sizeof (struct GNUNET_TIME_AbsoluteNBO));
-    name_tmp = (char *) &expire_tmp[1];
-    memcpy (name_tmp, name, name_len);
-    rd_ser = &name_tmp[name_len];
-    GNUNET_assert (rd_ser_len ==
-                  GNUNET_NAMESTORE_records_serialize (rd_count, rd, 
rd_ser_len, rd_ser));
-    return GNUNET_CRYPTO_ecc_verify (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN, 
sig_purpose, signature, public_key);
-  }
-}
-
-
-/**
  * Store an item in the namestore.  If the item is already present,
- * the expiration time is updated to the max of the existing time and
- * the new time.  This API is used by the authority of a zone.
+ * it is replaced with the new record.  Use an empty array to
+ * remove all records under the given name.
  *
  * @param h handle to the namestore
  * @param pkey private key of the zone
- * @param name name that is being mapped (at most 255 characters long)
- * @param rd_count number of records in 'rd' array
- * @param rd record data to store
+ * @param label name that is being mapped (at most 255 characters long)
+ * @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 'cont'
  * @return handle to abort the request
  */
 struct GNUNET_NAMESTORE_QueueEntry *
-GNUNET_NAMESTORE_record_put_by_authority (struct GNUNET_NAMESTORE_Handle *h,
-                                         const struct 
GNUNET_CRYPTO_EccPrivateKey *pkey,
-                                         const char *name,
-                                         unsigned int rd_count,
-                                         const struct 
GNUNET_NAMESTORE_RecordData *rd,
-                                         
GNUNET_NAMESTORE_ContinuationWithStatus cont,
-                                         void *cont_cls)
+GNUNET_NAMESTORE_records_store (struct GNUNET_NAMESTORE_Handle *h,
+                               const struct GNUNET_CRYPTO_EccPrivateKey *pkey,
+                               const char *label,
+                               unsigned int rd_count,
+                               const struct GNUNET_NAMESTORE_RecordData *rd,
+                               GNUNET_NAMESTORE_ContinuationWithStatus cont,
+                               void *cont_cls)
 {
   struct GNUNET_NAMESTORE_QueueEntry *qe;
   struct PendingMessage *pe;
@@ -1093,19 +1031,19 @@
   size_t msg_size;
   size_t name_len;
   uint32_t rid;
-  struct RecordCreateMessage *msg;
+  struct RecordStoreMessage *msg;
 
   GNUNET_assert (NULL != h);
   GNUNET_assert (NULL != pkey);
-  GNUNET_assert (NULL != name);
-  name_len = strlen(name) + 1;
+  GNUNET_assert (NULL != label);
+  name_len = strlen (label) + 1;
   if (name_len > MAX_NAME_LEN)
   {
     GNUNET_break (0);
     return NULL;
   }
   rid = get_op_id (h);
-  qe = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_QueueEntry));
+  qe = GNUNET_new (struct GNUNET_NAMESTORE_QueueEntry);
   qe->nsh = h;
   qe->cont = cont;
   qe->cont_cls = cont_cls;
@@ -1114,29 +1052,27 @@
 
   /* setup msg */
   rd_ser_len = GNUNET_NAMESTORE_records_get_size (rd_count, rd);
-  msg_size = sizeof (struct RecordCreateMessage) + name_len + rd_ser_len;
+  msg_size = sizeof (struct RecordStoreMessage) + name_len + rd_ser_len;
   pe = GNUNET_malloc (sizeof (struct PendingMessage) + msg_size);
   pe->size = msg_size;
-  pe->is_init = GNUNET_NO;
-  msg = (struct RecordCreateMessage *) &pe[1];
-  msg->gns_header.header.type = htons 
(GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE);
+  msg = (struct RecordStoreMessage *) &pe[1];
+  msg->gns_header.header.type = htons 
(GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE);
   msg->gns_header.header.size = htons (msg_size);
   msg->gns_header.r_id = htonl (rid);
   msg->name_len = htons (name_len);
   msg->rd_count = htons (rd_count);
   msg->rd_len = htons (rd_ser_len);
   msg->reserved = htons (0);
-  msg->expire = GNUNET_TIME_absolute_hton (GNUNET_TIME_UNIT_FOREVER_ABS);
   msg->private_key = *pkey;
 
   name_tmp = (char *) &msg[1];
-  memcpy (name_tmp, name, name_len);
+  memcpy (name_tmp, label, name_len);
   rd_ser = &name_tmp[name_len];
   GNUNET_break (rd_ser_len == GNUNET_NAMESTORE_records_serialize (rd_count, 
rd, rd_ser_len, rd_ser));
 
   LOG (GNUNET_ERROR_TYPE_DEBUG, 
        "Sending `%s' message for name `%s' with size %u\n", 
-       "NAMESTORE_RECORD_CREATE", name, msg_size);
+       "NAMESTORE_RECORD_STORE", label, msg_size);
   GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
   do_transmit(h);
   return qe;
@@ -1148,66 +1084,45 @@
  * will only be called once.  
  *
  * @param h handle to the namestore
- * @param zone zone to look up a record from
- * @param name name to look up
- * @param record_type desired record type, 0 for all
- * @param proc function to call on the matching records, or with
- *        NULL (rd_count == 0) if there are no matching records
+ * @param derived_hash hash of zone key combined with name to lookup
+ * @param proc function to call on the matching block, or with
+ *        NULL if there is no matching block
  * @param proc_cls closure for proc
- * @return a handle that can be used to
- *         cancel
+ * @return a handle that can be used to cancel
  */
 struct GNUNET_NAMESTORE_QueueEntry *
-GNUNET_NAMESTORE_lookup_record (struct GNUNET_NAMESTORE_Handle *h, 
-                             const struct GNUNET_CRYPTO_ShortHashCode *zone,
-                             const char *name,
-                             uint32_t record_type,
-                             GNUNET_NAMESTORE_RecordProcessor proc, void 
*proc_cls)
+GNUNET_NAMESTORE_lookup_block (struct GNUNET_NAMESTORE_Handle *h, 
+                              const struct GNUNET_HashCode *derived_hash,
+                              GNUNET_NAMESTORE_BlockProcessor proc, void 
*proc_cls)
 {
+
   struct GNUNET_NAMESTORE_QueueEntry *qe;
   struct PendingMessage *pe;
-  struct LookupNameMessage * msg;
+  struct LookupBlockMessage *msg;
   size_t msg_size;
-  size_t name_len;
   uint32_t rid;
 
   GNUNET_assert (NULL != h);
-  GNUNET_assert (NULL != zone);
-  GNUNET_assert (NULL != name);
+  GNUNET_assert (NULL != derived_hash);
   LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Looking for record of type %u under name `%s'\n",
-       record_type,
-       name);
-  name_len = strlen (name) + 1;
-  if ((name_len == 0) || (name_len > MAX_NAME_LEN))
-  {
-    GNUNET_break (0);
-    return NULL;
-  }
-
+       "Looking for block under %s\n",
+       GNUNET_h2s (derived_hash));
   rid = get_op_id(h);
-  qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry));
+  qe = GNUNET_new (struct GNUNET_NAMESTORE_QueueEntry);
   qe->nsh = h;
-  qe->proc = proc;
-  qe->proc_cls = proc_cls;
+  qe->block_proc = proc;
+  qe->block_proc_cls = proc_cls;
   qe->op_id = rid;
   GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, qe);
 
-  msg_size = sizeof (struct LookupNameMessage) + name_len;
-  pe = GNUNET_malloc(sizeof (struct PendingMessage) + msg_size);
+  msg_size = sizeof (struct LookupBlockMessage);
+  pe = GNUNET_malloc (sizeof (struct PendingMessage) + msg_size);
   pe->size = msg_size;
-  pe->is_init = GNUNET_NO;
-  msg = (struct LookupNameMessage *) &pe[1];
-  msg->gns_header.header.type = htons 
(GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME);
+  msg = (struct LookupBlockMessage *) &pe[1];
+  msg->gns_header.header.type = htons 
(GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_BLOCK);
   msg->gns_header.header.size = htons (msg_size);
   msg->gns_header.r_id = htonl (rid);
-  msg->record_type = htonl (record_type);
-  msg->name_len = htonl (name_len);
-  msg->zone = *zone;
-  memcpy (&msg[1], name, name_len);
-
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Sending `%s' message for name `%s'\n", "NAMESTORE_LOOKUP_NAME", name);
+  msg->query = *derived_hash;
   GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
   do_transmit(h);
   return qe;
@@ -1219,8 +1134,8 @@
  * Returns at most one result to the processor.
  *
  * @param h handle to the namestore
- * @param zone hash of public key of the zone to look up in, never NULL
- * @param value_zone hash of the public key of the target zone (value), never 
NULL
+ * @param zone public key of the zone to look up in, never NULL
+ * @param value_zone public key of the target zone (value), never NULL
  * @param proc function to call on the matching records, or with
  *        NULL (rd_count == 0) if there are no matching records
  * @param proc_cls closure for proc
@@ -1229,9 +1144,9 @@
  */
 struct GNUNET_NAMESTORE_QueueEntry *
 GNUNET_NAMESTORE_zone_to_name (struct GNUNET_NAMESTORE_Handle *h,
-                               const struct GNUNET_CRYPTO_ShortHashCode *zone,
-                               const struct GNUNET_CRYPTO_ShortHashCode 
*value_zone,
-                               GNUNET_NAMESTORE_RecordProcessor proc, void 
*proc_cls)
+                              const struct GNUNET_CRYPTO_EccPrivateKey *zone,
+                              const struct GNUNET_CRYPTO_EccPublicKey 
*value_zone,
+                              GNUNET_NAMESTORE_RecordMonitor proc, void 
*proc_cls)
 {
   struct GNUNET_NAMESTORE_QueueEntry *qe;
   struct PendingMessage *pe;
@@ -1243,7 +1158,7 @@
   GNUNET_assert (NULL != zone);
   GNUNET_assert (NULL != value_zone);
   rid = get_op_id(h);
-  qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry));
+  qe = GNUNET_new (struct GNUNET_NAMESTORE_QueueEntry);
   qe->nsh = h;
   qe->proc = proc;
   qe->proc_cls = proc_cls;
@@ -1251,9 +1166,8 @@
   GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, qe);
 
   msg_size = sizeof (struct ZoneToNameMessage);
-  pe = GNUNET_malloc(sizeof (struct PendingMessage) + msg_size);
+  pe = GNUNET_malloc (sizeof (struct PendingMessage) + msg_size);
   pe->size = msg_size;
-  pe->is_init = GNUNET_NO;
   msg = (struct ZoneToNameMessage *) &pe[1];
   msg->gns_header.header.type = htons 
(GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME);
   msg->gns_header.header.size = htons (msg_size);
@@ -1277,9 +1191,7 @@
  * "GNUNET_NAMESTORE_zone_iterator_next" is invoked.
  *
  * @param h handle to the namestore
- * @param zone zone to access, NULL for all zones
- * @param must_have_flags flags that must be set for the record to be returned
- * @param must_not_have_flags flags that must NOT be set for the record to be 
returned
+ * @param zone zone to access
  * @param proc function to call on each name from the zone; it
  *        will be called repeatedly with a value (if available)
  *        and always once at the end with a name of NULL.
@@ -1288,10 +1200,8 @@
  */
 struct GNUNET_NAMESTORE_ZoneIterator *
 GNUNET_NAMESTORE_zone_iteration_start (struct GNUNET_NAMESTORE_Handle *h,
-                                      const struct GNUNET_CRYPTO_ShortHashCode 
*zone,
-                                      enum GNUNET_NAMESTORE_RecordFlags 
must_have_flags,
-                                      enum GNUNET_NAMESTORE_RecordFlags 
must_not_have_flags,
-                                      GNUNET_NAMESTORE_RecordProcessor proc,
+                                      const struct GNUNET_CRYPTO_EccPrivateKey 
*zone,
+                                      GNUNET_NAMESTORE_RecordMonitor proc,
                                       void *proc_cls)
 {
   struct GNUNET_NAMESTORE_ZoneIterator *it;
@@ -1302,46 +1212,22 @@
 
   GNUNET_assert (NULL != h);
   rid = get_op_id(h);
-  it = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_ZoneIterator));
+  it = GNUNET_new (struct GNUNET_NAMESTORE_ZoneIterator);
   it->h = h;
   it->proc = proc;
   it->proc_cls = proc_cls;
   it->op_id = rid;
-  if (NULL != zone)
-  {
-    it->zone = *zone;
-    it->has_zone = GNUNET_YES;
-  }
-  else
-  {
-    memset (&it->zone, '\0', sizeof (it->zone));
-    it->has_zone = GNUNET_NO;
-  }
+  it->zone = *zone;
   GNUNET_CONTAINER_DLL_insert_tail (h->z_head, h->z_tail, it);
 
   msg_size = sizeof (struct ZoneIterationStartMessage);
   pe = GNUNET_malloc (sizeof (struct PendingMessage) + msg_size);
   pe->size = msg_size;
-  pe->is_init = GNUNET_NO;
   msg = (struct ZoneIterationStartMessage *) &pe[1];
   msg->gns_header.header.type = htons 
(GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START);
   msg->gns_header.header.size = htons (msg_size);
   msg->gns_header.r_id = htonl (rid);
-  if (NULL != zone)
-  {
-    LOG (GNUNET_ERROR_TYPE_DEBUG, 
-        "Sending `%s' message for zone `%s'\n", 
-        "ZONE_ITERATION_START", GNUNET_NAMESTORE_short_h2s(zone));
-    msg->zone = *zone;
-  }
-  else
-  {
-    LOG (GNUNET_ERROR_TYPE_DEBUG, 
-        "Sending `%s' message for all zones\n", "ZONE_ITERATION_START");
-    memset (&msg->zone, '\0', sizeof (msg->zone));
-  }
-  msg->must_have_flags = ntohs (must_have_flags);
-  msg->must_not_have_flags = ntohs (must_not_have_flags);
+  msg->zone = *zone;
   GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
   do_transmit(h);
   return it;
@@ -1365,9 +1251,8 @@
   GNUNET_assert (NULL != it);
   h = it->h;
   msg_size = sizeof (struct ZoneIterationNextMessage);
-  pe = GNUNET_malloc(sizeof (struct PendingMessage) + msg_size);
+  pe = GNUNET_malloc (sizeof (struct PendingMessage) + msg_size);
   pe->size = msg_size;
-  pe->is_init = GNUNET_NO;
   msg = (struct ZoneIterationNextMessage *) &pe[1];
   msg->gns_header.header.type = htons 
(GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT);
   msg->gns_header.header.size = htons (msg_size);
@@ -1397,19 +1282,15 @@
                               h->z_tail,
                               it);
   msg_size = sizeof (struct ZoneIterationStopMessage);
-  pe = GNUNET_malloc(sizeof (struct PendingMessage) + msg_size);
+  pe = GNUNET_malloc (sizeof (struct PendingMessage) + msg_size);
   pe->size = msg_size;
-  pe->is_init = GNUNET_NO;
   msg = (struct ZoneIterationStopMessage *) &pe[1];
   msg->gns_header.header.type = htons 
(GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP);
   msg->gns_header.header.size = htons (msg_size);
   msg->gns_header.r_id = htonl (it->op_id);
-  if (GNUNET_YES == it->has_zone)
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 
-               "Sending `%s' message for zone `%s'\n", "ZONE_ITERATION_STOP", 
GNUNET_NAMESTORE_short_h2s(&it->zone));
-  else
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 
-               "Sending `%s' message for all zones\n", "ZONE_ITERATION_STOP");
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 
+             "Sending `%s' message\n", 
+             "ZONE_ITERATION_STOP");
   GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
   do_transmit(h);
   GNUNET_free (it);

Modified: gnunet/src/namestore/namestore_api_common.c
===================================================================
--- gnunet/src/namestore/namestore_api_common.c 2013-08-12 18:00:43 UTC (rev 
28545)
+++ gnunet/src/namestore/namestore_api_common.c 2013-08-12 19:09:52 UTC (rev 
28546)
@@ -23,6 +23,7 @@
  * @brief API to access the NAMESTORE service
  * @author Martin Schanzenbach
  * @author Matthias Wachs
+ * @author Christian Grothoff
  */
 
 #include "platform.h"
@@ -40,6 +41,7 @@
 
 GNUNET_NETWORK_STRUCT_BEGIN
 
+
 /**
  * Internal format of a record in the serialized form.
  */
@@ -88,20 +90,29 @@
 
 
 /**
- * Convert a short hash to a string (for printing debug messages).
+ * Convert a zone key to a string (for printing debug messages).
  * This is one of the very few calls in the entire API that is
  * NOT reentrant!
  *
- * @param hc the short hash code
- * @return string form; will be overwritten by next call to GNUNET_h2s.
+ * @param z the zone key
+ * @return string form; will be overwritten by next call to 
GNUNET_NAMESTORE_z2s
  */
 const char *
-GNUNET_NAMESTORE_short_h2s (const struct GNUNET_CRYPTO_ShortHashCode * hc)
+GNUNET_NAMESTORE_z2s (const struct GNUNET_CRYPTO_EccPublicKey *z)
 {
-  static struct GNUNET_CRYPTO_ShortHashAsciiEncoded ret;
+  static char buf[sizeof (struct GNUNET_CRYPTO_EccPublicKey) * 8];
+  char *end;
 
-  GNUNET_CRYPTO_short_hash_to_enc (hc, &ret);
-  return (const char *) &ret;
+  end = GNUNET_STRINGS_data_to_string ((const unsigned char *) z, 
+                                      sizeof (struct 
GNUNET_CRYPTO_EccPublicKey),
+                                      buf, sizeof (buf));
+  if (NULL == end)
+  {
+    GNUNET_break (0);
+    return NULL;
+  }
+  *end = '\0';
+  return buf;
 }
 
 
@@ -273,20 +284,82 @@
  *
  * @param key the private key
  * @param expire block expiration
- * @param name the name
+ * @param label the name for the records
  * @param rd record data
  * @param rd_count number of records
+ * @param signature where to store the signature
+ */
+struct GNUNET_NAMESTORE_Block *
+GNUNET_NAMESTORE_block_create (const struct GNUNET_CRYPTO_EccPrivateKey *key,
+                              struct GNUNET_TIME_Absolute expire,
+                              const char *label,
+                              const struct GNUNET_NAMESTORE_RecordData *rd,
+                              unsigned int rd_count)
+{
+  GNUNET_break (0);
+  return NULL;
+}
+
+
+/**
+ * Check if a signature is valid.  This API is used by the GNS Block
+ * to validate signatures received from the network.
  *
- * @return the signature
+ * @param block block to verify
+ * @return GNUNET_OK if the signature is valid
  */
-struct GNUNET_CRYPTO_EccSignature *
+int
+GNUNET_NAMESTORE_block_verify (const struct GNUNET_NAMESTORE_Block *block)
+{
+  GNUNET_break (0);
+  return GNUNET_SYSERR;
+}
+
+
+/**
+ * Decrypt block.
+ *
+ * @param block block to decrypt
+ * @param zone_key public key of the zone
+ * @param label the name for the records
+ * @param proc function to call with the result
+ * @param proc_cls closure for proc
+ * @param GNUNET_OK on success, GNUNET_SYSERR if the block was 
+ *        not well-formed
+ */
+int
+GNUNET_NAMESTORE_block_decrypt (const struct GNUNET_NAMESTORE_Block *block,
+                               const struct GNUNET_CRYPTO_EccPublicKey 
*zone_key,
+                               const char *label,
+                               GNUNET_NAMESTORE_RecordMonitor proc,
+                               void *proc_cls)
+{
+  GNUNET_break (0);
+  return GNUNET_SYSERR;
+}
+
+
+#if OLD
+/**
+ * Sign name and records
+ *
+ * @param key the private key
+ * @param expire block expiration
+ * @param name the name
+ * @param rd record data
+ * @param rd_count number of records
+ * @param signature where to store the signature
+ */
+void
 GNUNET_NAMESTORE_create_signature (const struct GNUNET_CRYPTO_EccPrivateKey 
*key,
                                   struct GNUNET_TIME_Absolute expire,
                                   const char *name,
                                   const struct GNUNET_NAMESTORE_RecordData *rd,
-                                  unsigned int rd_count)
+                                  unsigned int rd_count,
+                                  struct GNUNET_CRYPTO_EccSignature *signature)
+                                  
 {
-  struct GNUNET_CRYPTO_EccSignature *sig;
+  struct GNUNET_CRYPTO_EccPrivateKey *dkey;
   struct GNUNET_CRYPTO_EccSignaturePurpose *sig_purpose;
   struct GNUNET_TIME_AbsoluteNBO expire_nbo;
   size_t rd_ser_len;
@@ -297,12 +370,7 @@
   int res;
   uint32_t sig_len;
 
-  if (NULL == name)
-  {
-    GNUNET_break (0);
-    return NULL;
-  }
-  sig = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignature));
+  dkey = GNUNET_CRYPTO_ecc_key_derive (key, name, "gns");
   name_len = strlen (name) + 1;
   expire_nbo = GNUNET_TIME_absolute_hton (expire);
   rd_ser_len = GNUNET_NAMESTORE_records_get_size (rd_count, rd);
@@ -321,17 +389,70 @@
     memcpy (name_tmp, name, name_len);
     rd_tmp = &name_tmp[name_len];
     memcpy (rd_tmp, rd_ser, rd_ser_len);
-    res = GNUNET_CRYPTO_ecc_sign (key, sig_purpose, sig);
+    GNUNET_assert (GNUNET_OK ==
+                  GNUNET_CRYPTO_ecc_sign (dkey, sig_purpose, signature));
     GNUNET_free (sig_purpose);
   }
-  if (GNUNET_OK != res)
+  GNUNET_CRYPTO_ecc_key_free (dkey);
+}
+
+
+/**
+ * Check if a signature is valid.  This API is used by the GNS Block
+ * to validate signatures received from the network.
+ *
+ * @param derived_key derived key of the zone and the label
+ * @param freshness time set for block expiration
+ * @param rd_count number of entries in 'rd' array
+ * @param rd array of records with data to store
+ * @param signature signature for all the records in the zone under the given 
name
+ * @return GNUNET_OK if the signature is valid
+ */
+int
+GNUNET_NAMESTORE_verify_signature (const struct GNUNET_CRYPTO_EccPublicKey 
*derived_key,
+                                   const struct GNUNET_TIME_Absolute freshness,
+                                   unsigned int rd_count,
+                                   const struct GNUNET_NAMESTORE_RecordData 
*rd,
+                                   const struct GNUNET_CRYPTO_EccSignature 
*signature)
+{
+  size_t rd_ser_len;
+  size_t name_len;
+  char *name_tmp;
+  char *rd_ser;
+  struct GNUNET_CRYPTO_EccSignaturePurpose *sig_purpose;
+  struct GNUNET_TIME_AbsoluteNBO *expire_tmp;
+  struct GNUNET_TIME_AbsoluteNBO expire_nbo = GNUNET_TIME_absolute_hton 
(freshness);
+  uint32_t sig_len;
+
+  GNUNET_assert (NULL != public_key);
+  GNUNET_assert (NULL != name);
+  GNUNET_assert (NULL != rd);
+  GNUNET_assert (NULL != signature);
+  name_len = strlen (name) + 1;
+  if (name_len > MAX_NAME_LEN)
   {
     GNUNET_break (0);
-    GNUNET_free (sig);
-    return NULL;
+    return GNUNET_SYSERR;
   }
-  return sig;
+  rd_ser_len = GNUNET_NAMESTORE_records_get_size (rd_count, rd);
+  sig_len = sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + sizeof (struct 
GNUNET_TIME_AbsoluteNBO) + rd_ser_len + name_len;
+  {
+    char sig_buf[sig_len] GNUNET_ALIGN;
+
+    sig_purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose *) sig_buf;
+    sig_purpose->size = htonl (sig_len);
+    sig_purpose->purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
+    expire_tmp = (struct GNUNET_TIME_AbsoluteNBO *) &sig_purpose[1];
+    memcpy (expire_tmp, &expire_nbo, sizeof (struct GNUNET_TIME_AbsoluteNBO));
+    name_tmp = (char *) &expire_tmp[1];
+    memcpy (name_tmp, name, name_len);
+    rd_ser = &name_tmp[name_len];
+    GNUNET_assert (rd_ser_len ==
+                  GNUNET_NAMESTORE_records_serialize (rd_count, rd, 
rd_ser_len, rd_ser));
+    return GNUNET_CRYPTO_ecc_verify (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN, 
sig_purpose, signature, public_key);
+  }
 }
+#endif
 
 
 /**
@@ -352,7 +473,6 @@
   const struct vpn_data *vpn;
   const struct srv_data *srv;
   const struct tlsa_data *tlsa;
-  struct GNUNET_CRYPTO_ShortHashAsciiEncoded enc;
   struct GNUNET_CRYPTO_HashAsciiEncoded s_peer;
   const char *cdata;
   char* vpn_str;
@@ -419,11 +539,9 @@
       return NULL;
     return GNUNET_strdup (tmp);
   case GNUNET_NAMESTORE_TYPE_PKEY:
-    if (data_size != sizeof (struct GNUNET_CRYPTO_ShortHashCode))
+    if (data_size != sizeof (struct GNUNET_CRYPTO_EccPublicKey))
       return NULL;
-    GNUNET_CRYPTO_short_hash_to_enc (data,
-                                    &enc);
-    return GNUNET_strdup ((const char*) enc.short_encoding);
+    return GNUNET_CRYPTO_ecc_public_key_to_string (data);
   case GNUNET_NAMESTORE_TYPE_PSEU:
     return GNUNET_strndup (data, data_size);
   case GNUNET_NAMESTORE_TYPE_LEHO:
@@ -505,7 +623,7 @@
 {
   struct in_addr value_a;
   struct in6_addr value_aaaa;
-  struct GNUNET_CRYPTO_ShortHashCode pkey;
+  struct GNUNET_CRYPTO_EccPublicKey pkey;
   struct soa_data *soa;
   struct vpn_data *vpn;
   struct tlsa_data *tlsa;
@@ -610,16 +728,16 @@
     return GNUNET_OK;
   case GNUNET_NAMESTORE_TYPE_PKEY:
     if (GNUNET_OK !=
-       GNUNET_CRYPTO_short_hash_from_string (s, &pkey))
+       GNUNET_CRYPTO_ecc_public_key_from_string (s, strlen (s), &pkey))
     {
       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                   _("Unable to parse PKEY record `%s'\n"),
                  s);
       return GNUNET_SYSERR;
     }
-    *data = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_ShortHashCode));
+    *data = GNUNET_new (struct GNUNET_CRYPTO_EccPublicKey);
     memcpy (*data, &pkey, sizeof (pkey));
-    *data_size = sizeof (struct GNUNET_CRYPTO_ShortHashCode);
+    *data_size = sizeof (struct GNUNET_CRYPTO_EccPublicKey);
     return GNUNET_OK;
   case GNUNET_NAMESTORE_TYPE_PSEU:
     *data = GNUNET_strdup (s);
@@ -676,6 +794,10 @@
 }
 
 
+/**
+ * Mapping of record type numbers to human-readable
+ * record type names.
+ */
 static struct { 
   const char *name; 
   uint32_t number; 
@@ -734,6 +856,7 @@
   return name_map[i].name;  
 }
 
+
 /**
  * Test if a given record is expired.
  * 
@@ -752,4 +875,42 @@
 }
 
 
+/**
+ * Calculate the DHT query for a given 'label' in a given zone.
+ * 
+ * @param zone private key of the zone
+ * @param label label of the record
+ * @return query hash to use for the query
+ */
+void
+GNUNET_NAMESTORE_query_from_private_key (const struct 
GNUNET_CRYPTO_EccPrivateKey *zone,
+                                        const char *label,
+                                        struct GNUNET_HashCode *query)
+{
+  struct GNUNET_CRYPTO_EccPublicKey pub;
+
+  GNUNET_CRYPTO_ecc_key_get_public (zone, &pub);
+  GNUNET_NAMESTORE_query_from_public_key (&pub, label, query);
+}
+
+
+/**
+ * Calculate the DHT query for a given 'label' in a given zone.
+ * 
+ * @param pub public key of the zone
+ * @param label label of the record
+ * @return query hash to use for the query
+ */
+void
+GNUNET_NAMESTORE_query_from_public_key (const struct 
GNUNET_CRYPTO_EccPublicKey *pub,
+                                       const char *label,
+                                       struct GNUNET_HashCode *query)
+{
+  struct GNUNET_CRYPTO_EccPublicKey pd;
+
+  GNUNET_CRYPTO_ecc_public_key_derive (pub, label, "gns", &pd);
+  GNUNET_CRYPTO_hash (&pd, sizeof (pd), query);
+}
+
+
 /* end of namestore_common.c */

Modified: gnunet/src/namestore/namestore_api_monitor.c
===================================================================
--- gnunet/src/namestore/namestore_api_monitor.c        2013-08-12 18:00:43 UTC 
(rev 28545)
+++ gnunet/src/namestore/namestore_api_monitor.c        2013-08-12 19:09:52 UTC 
(rev 28546)
@@ -73,12 +73,8 @@
   /**
    * Monitored zone.
    */
-  struct GNUNET_CRYPTO_ShortHashCode zone;
+  struct GNUNET_CRYPTO_EccPrivateKey zone;
 
-  /**
-   * GNUNET_YES if we monitor all zones, GNUNET_NO if we only monitor 'zone'.
-   */
-  int all_zones;
 };
 
 
@@ -108,8 +104,7 @@
     GNUNET_CLIENT_disconnect (zm->h);
   zm->monitor (zm->cls,
               NULL,
-              GNUNET_TIME_UNIT_ZERO_ABS,
-              NULL, 0, NULL, NULL);
+              NULL, 0, NULL);
   GNUNET_assert (NULL != (zm->h = GNUNET_CLIENT_connect ("namestore", 
zm->cfg)));
   zm->th = GNUNET_CLIENT_notify_transmit_ready (zm->h,
                                                sizeof (struct 
ZoneMonitorStartMessage),
@@ -132,7 +127,7 @@
                const struct GNUNET_MessageHeader *msg)
 {
   struct GNUNET_NAMESTORE_ZoneMonitor *zm = cls;
-  const struct LookupNameResponseMessage *lrm;
+  const struct RecordResultMessage *lrm;
   size_t lrm_len;
   size_t exp_lrm_len;
   size_t name_len;
@@ -140,7 +135,6 @@
   unsigned rd_count;
   const char *name_tmp;
   const char *rd_ser_tmp;
-  struct GNUNET_TIME_Absolute expire;
 
   if (NULL == msg)
   {
@@ -158,20 +152,19 @@
       zm->sync_cb (zm->cls);
     return;
   }
-  if ( (ntohs (msg->size) < sizeof (struct LookupNameResponseMessage)) ||
-       (GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPONSE != ntohs 
(msg->type) ) )
+  if ( (ntohs (msg->size) < sizeof (struct RecordResultMessage)) ||
+       (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT != ntohs (msg->type) ) )
   {
     GNUNET_break (0);
     reconnect (zm);
     return;
   }
-  lrm = (const struct LookupNameResponseMessage *) msg;
+  lrm = (const struct RecordResultMessage *) msg;
   lrm_len = ntohs (lrm->gns_header.header.size);
   rd_len = ntohs (lrm->rd_len);
   rd_count = ntohs (lrm->rd_count);
   name_len = ntohs (lrm->name_len);
-  expire = GNUNET_TIME_absolute_ntoh (lrm->expire);
-  exp_lrm_len = sizeof (struct LookupNameResponseMessage) + name_len + rd_len;
+  exp_lrm_len = sizeof (struct RecordResultMessage) + name_len + rd_len;
   if (lrm_len != exp_lrm_len)
   {
     GNUNET_break (0);
@@ -206,9 +199,9 @@
                           zm,
                           GNUNET_TIME_UNIT_FOREVER_REL);
     zm->monitor (zm->cls, 
-                &lrm->public_key, expire, 
+                &lrm->private_key,
                 name_tmp, 
-                rd_count, rd, NULL);
+                rd_count, rd);
   }
 }
 
@@ -239,7 +232,6 @@
   sm.gns_header.header.size = htons (sizeof (struct ZoneMonitorStartMessage));
   sm.gns_header.r_id = htonl (0);
   sm.zone = zm->zone;
-  sm.all_zones = htonl (zm->all_zones);
   memcpy (buf, &sm, sizeof (sm));
   GNUNET_CLIENT_receive (zm->h,
                         &handle_updates,
@@ -255,7 +247,7 @@
  * a record changes.
  *
  * @param cfg configuration to use to connect to namestore
- * @param zone zone to monitor, NULL for all zones
+ * @param zone zone to monitor
  * @param monitor function to call on zone changes
  * @param sync_cb function called when we're in sync with the namestore
  * @param cls closure for 'monitor' and 'sync_cb'
@@ -263,7 +255,7 @@
  */
 struct GNUNET_NAMESTORE_ZoneMonitor *
 GNUNET_NAMESTORE_zone_monitor_start (const struct GNUNET_CONFIGURATION_Handle 
*cfg,
-                                    const struct GNUNET_CRYPTO_ShortHashCode 
*zone,
+                                    const struct GNUNET_CRYPTO_EccPrivateKey 
*zone,
                                     GNUNET_NAMESTORE_RecordMonitor monitor,
                                     
GNUNET_NAMESTORE_RecordsSynchronizedCallback sync_cb,
                                     void *cls)
@@ -276,10 +268,7 @@
   zm = GNUNET_new (struct GNUNET_NAMESTORE_ZoneMonitor);
   zm->cfg = cfg;
   zm->h = client;
-  if (NULL == zone)
-    zm->all_zones = GNUNET_YES;
-  else
-    zm->zone = *zone;
+  zm->zone = *zone;
   zm->monitor = monitor;
   zm->sync_cb = sync_cb;
   zm->cls = cls;

Modified: gnunet/src/namestore/plugin_namestore_sqlite.c
===================================================================
--- gnunet/src/namestore/plugin_namestore_sqlite.c      2013-08-12 18:00:43 UTC 
(rev 28545)
+++ gnunet/src/namestore/plugin_namestore_sqlite.c      2013-08-12 19:09:52 UTC 
(rev 28546)
@@ -31,14 +31,14 @@
 #include <sqlite3.h>
 
 /**
- * After how many ms "busy" should a DB operation fail for good?
- * A low value makes sure that we are more responsive to requests
- * (especially PUTs).  A high value guarantees a higher success
- * rate (SELECTs in iterate can take several seconds despite LIMIT=1).
+ * After how many ms "busy" should a DB operation fail for good?  A
+ * low value makes sure that we are more responsive to requests
+ * (especially PUTs).  A high value guarantees a higher success rate
+ * (SELECTs in iterate can take several seconds despite LIMIT=1).
  *
  * The default value of 1s should ensure that users do not experience
- * huge latencies while at the same time allowing operations to succeed
- * with reasonable probability.
+ * huge latencies while at the same time allowing operations to
+ * succeed with reasonable probability.
  */
 #define BUSY_TIMEOUT_MS 1000
 
@@ -72,45 +72,40 @@
   sqlite3 *dbh;
 
   /**
-   * Precompiled SQL for put record
+   * Precompiled SQL for caching a block
    */
-  sqlite3_stmt *put_records;
+  sqlite3_stmt *cache_block;
 
   /**
-   * Precompiled SQL for remove record
+   * Precompiled SQL for looking up a block
    */
-  sqlite3_stmt *remove_records;
+  sqlite3_stmt *lookup_block;
 
   /**
-   * Precompiled SQL for iterate over all records.
+   * Precompiled SQL for removing expired blocks
    */
-  sqlite3_stmt *iterate_all;
+  sqlite3_stmt *expire_blocks;
 
   /**
-   * Precompiled SQL for iterate records with same name.
+   * Precompiled SQL to store records.
    */
-  sqlite3_stmt *iterate_by_name;
+  sqlite3_stmt *store_records;
 
   /**
-   * Precompiled SQL for iterate records with same zone.
+   * Precompiled SQL to deltete existing records.
    */
-  sqlite3_stmt *iterate_by_zone;
+  sqlite3_stmt *delete_records;
 
   /**
-   * Precompiled SQL for iterate records with same name and zone.
+   * Precompiled SQL for iterate records within a zone.
    */
-  sqlite3_stmt *iterate_records;
+  sqlite3_stmt *iterate_zone;
 
   /**
-   * Precompiled SQL to get the name for a given zone-value.
+   * Precompiled SQL to for reverse lookup based on PKEY.
    */
   sqlite3_stmt *zone_to_name;
 
-  /**
-   * Precompiled SQL for delete zone
-   */
-  sqlite3_stmt *delete_zone;
-
 };
 
 
@@ -147,23 +142,17 @@
 {
   /* create indices */
   if ( (SQLITE_OK !=
-       sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_zone_name_rv ON 
ns091records (zone_hash,record_name_hash,rvalue)",
+       sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_query_hash ON 
ns096blocks (query,expiration_time)",
                      NULL, NULL, NULL)) ||
        (SQLITE_OK !=
-       sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_zone_delegation ON 
ns091records (zone_hash,zone_delegation)",
+       sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_block_expiration ON 
ns096blocks (expiration_time)",
                      NULL, NULL, NULL)) ||
        (SQLITE_OK !=
-       sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_zone_rv ON 
ns091records (zone_hash,rvalue)",
+       sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_pkey_reverse ON 
ns096records (zone_private_key,pkey_hash)",
                      NULL, NULL, NULL)) ||
        (SQLITE_OK !=
-       sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_zone ON ns091records 
(zone_hash)",
-                     NULL, NULL, NULL)) ||
-       (SQLITE_OK !=
-       sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_name_rv ON 
ns091records (record_name_hash,rvalue)",
-                     NULL, NULL, NULL)) ||
-       (SQLITE_OK !=
-       sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_rv ON ns091records 
(rvalue)",
-                     NULL, NULL, NULL)) )    
+       sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_pkey_iter ON 
ns096records (zone_private_key,rvalue)",
+                     NULL, NULL, NULL)) )
     LOG (GNUNET_ERROR_TYPE_ERROR, 
         "Failed to create indices: %s\n", sqlite3_errmsg (dbh));
 }
@@ -255,22 +244,38 @@
   /* Create tables */
   CHECK (SQLITE_OK ==
          sq_prepare (plugin->dbh,
-                     "SELECT 1 FROM sqlite_master WHERE tbl_name = 
'ns091records'",
+                     "SELECT 1 FROM sqlite_master WHERE tbl_name = 
'ns096blocks'",
                      &stmt));
   if ((sqlite3_step (stmt) == SQLITE_DONE) &&
       (sqlite3_exec
        (plugin->dbh,
-        "CREATE TABLE ns091records (" 
-        " zone_key BLOB NOT NULL DEFAULT ''," 
-        " zone_delegation BLOB NOT NULL DEFAULT ''," 
-        " zone_hash BLOB NOT NULL DEFAULT ''," 
+        "CREATE TABLE ns096blocks (" 
+        " query BLOB NOT NULL DEFAULT ''," 
+        " block BLOB NOT NULL DEFAULT ''," 
+        " expiration_time INT8 NOT NULL DEFAULT 0" 
+       ")", 
+       NULL, NULL, NULL) != SQLITE_OK))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite3_exec");
+    sqlite3_finalize (stmt);
+    return GNUNET_SYSERR;
+  }
+  sqlite3_finalize (stmt);
+
+  CHECK (SQLITE_OK ==
+         sq_prepare (plugin->dbh,
+                     "SELECT 1 FROM sqlite_master WHERE tbl_name = 
'ns096records'",
+                     &stmt));
+  if ((sqlite3_step (stmt) == SQLITE_DONE) &&
+      (sqlite3_exec
+       (plugin->dbh,
+        "CREATE TABLE ns096records (" 
+        " zone_private_key BLOB NOT NULL DEFAULT ''," 
+        " pkey_hash BLOB," 
+       " rvalue INT8 NOT NULL DEFAULT '',"
        " record_count INT NOT NULL DEFAULT 0,"
         " record_data BLOB NOT NULL DEFAULT '',"
-        " block_expiration_time INT8 NOT NULL DEFAULT 0," 
-        " signature BLOB NOT NULL DEFAULT '',"
-        " record_name TEXT NOT NULL DEFAULT ''," 
-        " record_name_hash BLOB NOT NULL DEFAULT ''," 
-       " rvalue INT8 NOT NULL DEFAULT ''"
+        " label TEXT NOT NULL DEFAULT ''" 
        ")", 
        NULL, NULL, NULL) != SQLITE_OK))
   {
@@ -284,42 +289,35 @@
 
   if ((sq_prepare
        (plugin->dbh,
-        "INSERT INTO ns091records (zone_key, record_name, record_count, 
record_data, block_expiration_time, signature, zone_delegation, zone_hash, 
record_name_hash, rvalue) VALUES "
-       "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
-        &plugin->put_records) != SQLITE_OK) ||
+        "INSERT INTO ns096blocks (query,block,expiration_time) VALUES (?, ?, 
?)",
+        &plugin->cache_block) != SQLITE_OK) ||
       (sq_prepare
        (plugin->dbh,
-        "DELETE FROM ns091records WHERE zone_hash=? AND record_name_hash=?",
-        &plugin->remove_records) != SQLITE_OK) ||
+        "DELETE FROM ns096blocks WHERE expiration_time<?",
+        &plugin->expire_blocks) != SQLITE_OK) ||
       (sq_prepare
        (plugin->dbh,
-        "SELECT zone_key, record_name, record_count, record_data, 
block_expiration_time, signature"
-       " FROM ns091records WHERE zone_hash=? AND record_name_hash=? ORDER BY 
rvalue LIMIT 1 OFFSET ?",
-        &plugin->iterate_records) != SQLITE_OK) ||
+        "SELECT block FROM ns096blocks WHERE query=? ORDER BY expiration_time 
DESC LIMIT 1",
+        &plugin->lookup_block) != SQLITE_OK) ||
       (sq_prepare
        (plugin->dbh,
-        "SELECT zone_key, record_name, record_count, record_data, 
block_expiration_time, signature" 
-       " FROM ns091records WHERE zone_hash=? ORDER BY rvalue  LIMIT 1 OFFSET 
?",
-        &plugin->iterate_by_zone) != SQLITE_OK) ||
+        "INSERT INTO ns096records (zone_private_key, pkey_hash, rvalue, 
record_count, record_data, label)"
+       " VALUES (?, ?, ?, ?, ?, ?)",
+        &plugin->store_records) != SQLITE_OK) ||
       (sq_prepare
        (plugin->dbh,
-        "SELECT zone_key, record_name, record_count, record_data, 
block_expiration_time, signature" 
-       " FROM ns091records WHERE record_name_hash=? ORDER BY rvalue LIMIT 1 
OFFSET ?",
-        &plugin->iterate_by_name) != SQLITE_OK) ||
+        "DELETE FROM ns096records WHERE zone_private_key=? AND label=?",
+        &plugin->delete_records) != SQLITE_OK) ||
       (sq_prepare
-       (plugin->dbh,
-        "SELECT zone_key, record_name, record_count, record_data, 
block_expiration_time, signature" 
-       " FROM ns091records ORDER BY rvalue LIMIT 1 OFFSET ?",
-        &plugin->iterate_all) != SQLITE_OK) ||
-      (sq_prepare
-       (plugin->dbh,
-        "SELECT zone_key, record_name, record_count, record_data, 
block_expiration_time, signature"
-       " FROM ns091records WHERE zone_hash=? AND zone_delegation=?",
+       (plugin->dbh,
+        "SELECT record_count,record_data,label"
+       " FROM ns096records WHERE zone_private_key=? AND pkey_hash=?",
         &plugin->zone_to_name) != SQLITE_OK) ||
       (sq_prepare
        (plugin->dbh,
-        "DELETE FROM ns091records WHERE zone_hash=?",
-        &plugin->delete_zone) != SQLITE_OK) )
+       "SELECT record_count,record_data,label" 
+       " FROM ns096records WHERE zone_private_key=? ORDER BY rvalue LIMIT 1 
OFFSET ?",
+       &plugin->iterate_zone) != SQLITE_OK) )
   {
     LOG_SQLITE (plugin,GNUNET_ERROR_TYPE_ERROR, "precompiling");
     return GNUNET_SYSERR;
@@ -339,22 +337,20 @@
   int result;
   sqlite3_stmt *stmt;
 
-  if (NULL != plugin->put_records)
-    sqlite3_finalize (plugin->put_records);
-  if (NULL != plugin->remove_records)
-    sqlite3_finalize (plugin->remove_records);
-  if (NULL != plugin->iterate_records)
-    sqlite3_finalize (plugin->iterate_records);
-  if (NULL != plugin->iterate_by_zone)
-    sqlite3_finalize (plugin->iterate_by_zone);
-  if (NULL != plugin->iterate_by_name)
-    sqlite3_finalize (plugin->iterate_by_name);
-  if (NULL != plugin->iterate_all)
-    sqlite3_finalize (plugin->iterate_all);
+  if (NULL != plugin->cache_block)
+    sqlite3_finalize (plugin->cache_block);
+  if (NULL != plugin->expire_blocks)
+    sqlite3_finalize (plugin->expire_blocks);
+  if (NULL != plugin->lookup_block)
+    sqlite3_finalize (plugin->lookup_block);
+  if (NULL != plugin->store_records)
+    sqlite3_finalize (plugin->store_records);
+  if (NULL != plugin->delete_records)
+    sqlite3_finalize (plugin->delete_records);
+  if (NULL != plugin->iterate_zone)
+    sqlite3_finalize (plugin->iterate_zone);
   if (NULL != plugin->zone_to_name)
     sqlite3_finalize (plugin->zone_to_name);
-  if (NULL != plugin->delete_zone)
-    sqlite3_finalize (plugin->delete_zone);
   result = sqlite3_close (plugin->dbh);
   if (result == SQLITE_BUSY)
   {
@@ -381,104 +377,215 @@
 
 
 /**
- * Removes any existing record in the given zone with the same name.
+ * Removes any expired block.
  *
- * @param cls closure (internal context for the plugin)
- * @param zone hash of the public key of the zone
- * @param name name to remove (at most 255 characters long)
- * @return GNUNET_OK on success
+ * @param plugin the plugin
  */
-static int 
-namestore_sqlite_remove_records (void *cls, 
-                                const struct GNUNET_CRYPTO_ShortHashCode *zone,
-                                const char *name)
+static void
+namestore_sqlite_expire_blocks (struct Plugin *plugin)
 {
-  struct Plugin *plugin = cls;
-  struct GNUNET_CRYPTO_ShortHashCode nh;
-  size_t name_len;
+  struct GNUNET_TIME_Absolute now;
   int n;
 
-  name_len = strlen (name);
-  GNUNET_CRYPTO_short_hash (name, name_len, &nh);
-
-  if ((SQLITE_OK != sqlite3_bind_blob (plugin->remove_records, 1, zone, sizeof 
(struct GNUNET_CRYPTO_ShortHashCode), SQLITE_STATIC)) ||
-      (SQLITE_OK != sqlite3_bind_blob (plugin->remove_records, 2, &nh, sizeof 
(struct GNUNET_CRYPTO_ShortHashCode), SQLITE_STATIC)))
+  now = GNUNET_TIME_absolute_get ();
+  if (SQLITE_OK != sqlite3_bind_int64 (plugin->expire_blocks, 
+                                      1, now.abs_value_us))
   {
     LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                 "sqlite3_bind_XXXX");
-    if (SQLITE_OK != sqlite3_reset (plugin->remove_records))
+    if (SQLITE_OK != sqlite3_reset (plugin->expire_blocks))
       LOG_SQLITE (plugin,
                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                   "sqlite3_reset");
-    return GNUNET_SYSERR;
+    return;
   }
-  n = sqlite3_step (plugin->remove_records);
-  if (SQLITE_OK != sqlite3_reset (plugin->remove_records))
+  n = sqlite3_step (plugin->expire_blocks);
+  if (SQLITE_OK != sqlite3_reset (plugin->expire_blocks))
     LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                 "sqlite3_reset");
   switch (n)
   {
   case SQLITE_DONE:
-    GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Record removed\n");
-    return GNUNET_OK;
+    GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Records expired\n");
+    return;
   case SQLITE_BUSY:
     LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK,
                 "sqlite3_step");
-    return GNUNET_NO;
+    return;
   default:
     LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                 "sqlite3_step");
+    return;
+  }
+}
+
+
+/**
+ * Cache a block in the datastore.
+ *
+ * @param cls closure (internal context for the plugin)
+ * @param block block to cache
+ * @return GNUNET_OK on success, else GNUNET_SYSERR
+ */
+static int 
+namestore_sqlite_cache_block (void *cls, 
+                             const struct GNUNET_NAMESTORE_Block *block)
+{
+  struct Plugin *plugin = cls;
+  struct GNUNET_HashCode query;
+  struct GNUNET_TIME_Absolute expiration;
+  size_t block_size;
+  int n;
+
+  namestore_sqlite_expire_blocks (plugin);
+  GNUNET_CRYPTO_hash (&block->derived_key, 
+                     sizeof (struct GNUNET_CRYPTO_EccPublicKey), 
+                     &query);
+  expiration = GNUNET_TIME_absolute_ntoh (block->expiration_time);
+  block_size = ntohl (block->purpose.size) + 
+    sizeof (struct GNUNET_CRYPTO_EccPublicKey) + 
+    sizeof (struct GNUNET_CRYPTO_EccSignature); 
+  if (block_size > 64 * 65536)
+  {
+    GNUNET_break (0);
     return GNUNET_SYSERR;
   }
+  if ((SQLITE_OK != sqlite3_bind_blob (plugin->cache_block, 1, &query, sizeof 
(struct GNUNET_HashCode), SQLITE_STATIC)) ||
+      (SQLITE_OK != sqlite3_bind_blob (plugin->cache_block, 2, block, 
block_size, SQLITE_STATIC)) ||
+      (SQLITE_OK != sqlite3_bind_int64 (plugin->cache_block, 3, 
expiration.abs_value_us)))
+  {
+    LOG_SQLITE (plugin, 
+               GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+               "sqlite3_bind_XXXX");
+    if (SQLITE_OK != sqlite3_reset (plugin->cache_block))
+      LOG_SQLITE (plugin, 
+                 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                 "sqlite3_reset");
+    return GNUNET_SYSERR;
+    
+  }
+  n = sqlite3_step (plugin->cache_block);
+  if (SQLITE_OK != sqlite3_reset (plugin->cache_block))
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+               "sqlite3_reset");
+  switch (n)
+  {
+  case SQLITE_DONE:
+    GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Record stored\n");
+    return GNUNET_OK;
+  case SQLITE_BUSY:
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK,
+               "sqlite3_step");
+    return GNUNET_NO;
+  default:
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+               "sqlite3_step");
+    return GNUNET_SYSERR;  
+  }
 }
 
 
 /**
+ * Get the block for a particular zone and label in the
+ * datastore.  Will return at most one result to the iterator.
+ *
+ * @param cls closure (internal context for the plugin)
+ * @param query hash of public key derived from the zone and the label
+ * @param iter function to call with the result
+ * @param iter_cls closure for iter
+ * @return GNUNET_OK on success, GNUNET_NO if there were no results, 
GNUNET_SYSERR on error
+ *         'iter' will have been called unless the return value is 
'GNUNET_SYSERR'
+ */
+static int
+namestore_sqlite_lookup_block (void *cls, 
+                              const struct GNUNET_HashCode *query,
+                              GNUNET_NAMESTORE_BlockCallback iter, void 
*iter_cls)
+{
+  struct Plugin *plugin = cls;
+  int ret;
+  int sret;
+  size_t block_size;
+  const struct GNUNET_NAMESTORE_Block *block;
+
+  if (SQLITE_OK != sqlite3_bind_blob (plugin->lookup_block, 1,
+                                     query, sizeof (struct GNUNET_HashCode),
+                                     SQLITE_STATIC))
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+               "sqlite3_bind_XXXX");
+    if (SQLITE_OK != sqlite3_reset (plugin->lookup_block))
+      LOG_SQLITE (plugin,
+                 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                 "sqlite3_reset");
+    return GNUNET_SYSERR;
+  }      
+
+  ret = GNUNET_NO;
+  if (SQLITE_ROW == (sret = sqlite3_step (plugin->lookup_block)))
+  {     
+    ret = GNUNET_YES;
+    block = sqlite3_column_blob (plugin->lookup_block, 0);
+    block_size = sqlite3_column_bytes (plugin->lookup_block, 0);
+    if ( (block_size < sizeof (struct GNUNET_NAMESTORE_Block)) ||
+        (ntohl (block->purpose.size) + 
+         sizeof (struct GNUNET_CRYPTO_EccPublicKey) + 
+         sizeof (struct GNUNET_CRYPTO_EccSignature) != block_size) )
+    {
+      GNUNET_break (0);
+      ret = GNUNET_SYSERR;     
+    }
+    else
+    {
+      iter (iter_cls, block);    
+    }
+  }
+  else
+  {
+    if (SQLITE_DONE != sret)
+      LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite_step");
+    iter (iter_cls, NULL);
+  }
+  if (SQLITE_OK != sqlite3_reset (plugin->lookup_block))
+    LOG_SQLITE (plugin,
+               GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+               "sqlite3_reset");
+  return ret;
+}
+
+
+/**
  * Store a record in the datastore.  Removes any existing record in the
  * same zone with the same name.
  *
  * @param cls closure (internal context for the plugin)
- * @param zone_key public key of the zone
- * @param expire when does the corresponding block in the DHT expire (until
- *               when should we never do a DHT lookup for the same name again)?
- * @param name name that is being mapped (at most 255 characters long)
+ * @param zone_key private key of the zone
+ * @param label name that is being mapped (at most 255 characters long)
  * @param rd_count number of entries in 'rd' array
  * @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, else GNUNET_SYSERR
  */
 static int 
-namestore_sqlite_put_records (void *cls, 
-                             const struct GNUNET_CRYPTO_EccPublicKey *zone_key,
-                             struct GNUNET_TIME_Absolute expire,
-                             const char *name,
-                             unsigned int rd_count,
-                             const struct GNUNET_NAMESTORE_RecordData *rd,
-                             const struct GNUNET_CRYPTO_EccSignature 
*signature)
+namestore_sqlite_store_records (void *cls, 
+                               const struct GNUNET_CRYPTO_EccPrivateKey 
*zone_key,
+                               const char *label,
+                               unsigned int rd_count,
+                               const struct GNUNET_NAMESTORE_RecordData *rd)
 {
   struct Plugin *plugin = cls;
   int n;
-  struct GNUNET_CRYPTO_ShortHashCode zone;
-  struct GNUNET_CRYPTO_ShortHashCode zone_delegation;
-  struct GNUNET_CRYPTO_ShortHashCode nh;
-  size_t name_len;
+  struct GNUNET_HashCode pkey_hash;
   uint64_t rvalue;
   size_t data_size;
   unsigned int i;
 
-  GNUNET_CRYPTO_short_hash (zone_key, sizeof (struct 
GNUNET_CRYPTO_EccPublicKey), &zone);
-  (void) namestore_sqlite_remove_records (plugin, &zone, name);
-  name_len = strlen (name);
-  GNUNET_CRYPTO_short_hash (name, name_len, &nh);
-  memset (&zone_delegation, 0, sizeof (zone_delegation));
+  memset (&pkey_hash, 0, sizeof (pkey_hash));
   for (i=0;i<rd_count;i++)
-    if (rd[i].record_type == GNUNET_NAMESTORE_TYPE_PKEY)
+    if (GNUNET_NAMESTORE_TYPE_PKEY == rd[i].record_type)
     {
-      GNUNET_assert (sizeof (struct GNUNET_CRYPTO_ShortHashCode) == 
rd[i].data_size);
-      memcpy (&zone_delegation,
-             rd[i].data,
-             sizeof (struct GNUNET_CRYPTO_ShortHashCode));
+      GNUNET_break (sizeof (struct GNUNET_CRYPTO_EccPublicKey) == 
rd[i].data_size);
+      GNUNET_CRYPTO_hash (rd[i].data,
+                         rd[i].data_size,
+                         &pkey_hash);
       break;
     }
   rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX);
@@ -497,31 +604,52 @@
       GNUNET_break (0);
       return GNUNET_SYSERR;
     }
-    if ((SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 1, zone_key, 
sizeof (struct GNUNET_CRYPTO_EccPublicKey), SQLITE_STATIC)) ||
-       (SQLITE_OK != sqlite3_bind_text (plugin->put_records, 2, name, -1, 
SQLITE_STATIC)) ||
-       (SQLITE_OK != sqlite3_bind_int (plugin->put_records, 3, rd_count)) ||
-       (SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 4, data, 
data_size, SQLITE_STATIC)) ||
-       (SQLITE_OK != sqlite3_bind_int64 (plugin->put_records, 5, 
expire.abs_value_us)) ||
-       (SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 6, signature, 
sizeof (struct GNUNET_CRYPTO_EccSignature), SQLITE_STATIC)) ||
-       (SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 7, 
&zone_delegation, sizeof (struct GNUNET_CRYPTO_ShortHashCode), SQLITE_STATIC)) 
||
-       (SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 8, &zone, sizeof 
(struct GNUNET_CRYPTO_ShortHashCode), SQLITE_STATIC)) ||
-       (SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 9, &nh, sizeof 
(struct GNUNET_CRYPTO_ShortHashCode), SQLITE_STATIC)) ||
-       (SQLITE_OK != sqlite3_bind_int64 (plugin->put_records, 10, rvalue)) )
+
+    /* First delete 'old' records */
+    if ((SQLITE_OK != sqlite3_bind_blob (plugin->delete_records, 1, 
+                                        zone_key, sizeof (struct 
GNUNET_CRYPTO_EccPrivateKey), SQLITE_STATIC)) ||
+       (SQLITE_OK != sqlite3_bind_text (plugin->delete_records, 2, label, -1, 
SQLITE_STATIC)))
     {
       LOG_SQLITE (plugin, 
                  GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                  "sqlite3_bind_XXXX");
-      if (SQLITE_OK != sqlite3_reset (plugin->put_records))
+      if (SQLITE_OK != sqlite3_reset (plugin->delete_records))
        LOG_SQLITE (plugin, 
                    GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                    "sqlite3_reset");
       return GNUNET_SYSERR;
       
     }
-    n = sqlite3_step (plugin->put_records);
-    if (SQLITE_OK != sqlite3_reset (plugin->put_records))
+    n = sqlite3_step (plugin->delete_records);
+    if (SQLITE_OK != sqlite3_reset (plugin->delete_records))
       LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                  "sqlite3_reset");
+
+    if (0 != rd_count)
+    {
+      if ((SQLITE_OK != sqlite3_bind_blob (plugin->store_records, 1, 
+                                          zone_key, sizeof (struct 
GNUNET_CRYPTO_EccPrivateKey), SQLITE_STATIC)) ||
+         (SQLITE_OK != sqlite3_bind_blob (plugin->store_records, 2,
+                                          &pkey_hash, sizeof (struct 
GNUNET_HashCode), SQLITE_STATIC)) ||
+         (SQLITE_OK != sqlite3_bind_int64 (plugin->store_records, 3, rvalue)) 
||
+         (SQLITE_OK != sqlite3_bind_int (plugin->store_records, 4, rd_count)) 
||
+         (SQLITE_OK != sqlite3_bind_blob (plugin->store_records, 5, data, 
data_size, SQLITE_STATIC)) ||
+         (SQLITE_OK != sqlite3_bind_text (plugin->store_records, 6, label, -1, 
SQLITE_STATIC)))
+      {
+       LOG_SQLITE (plugin, 
+                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                   "sqlite3_bind_XXXX");
+       if (SQLITE_OK != sqlite3_reset (plugin->store_records))
+         LOG_SQLITE (plugin, 
+                     GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                     "sqlite3_reset");
+       return GNUNET_SYSERR;   
+      }
+      n = sqlite3_step (plugin->store_records);
+      if (SQLITE_OK != sqlite3_reset (plugin->store_records))
+       LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+                   "sqlite3_reset");
+    }
   }
   switch (n)
   {
@@ -547,6 +675,7 @@
  *
  * @param plugin plugin context
  * @param stmt to run (and then clean up)
+ * @param zone_key private key of the zone
  * @param iter iterator to call with the result
  * @param iter_cls closure for 'iter'
  * @return GNUNET_OK on success, GNUNET_NO if there were no results, 
GNUNET_SYSERR on error
@@ -554,38 +683,27 @@
 static int
 get_record_and_call_iterator (struct Plugin *plugin,
                              sqlite3_stmt *stmt,                             
+                             const struct GNUNET_CRYPTO_EccPrivateKey 
*zone_key,
                              GNUNET_NAMESTORE_RecordIterator iter, void 
*iter_cls)
 {
-  int ret;
-  int sret;
   unsigned int record_count;
   size_t data_size;
-  const struct GNUNET_CRYPTO_EccPublicKey *zone_key;
-  const struct GNUNET_CRYPTO_EccSignature *sig;
-  struct GNUNET_TIME_Absolute expiration;
   const char *data;
-  const char *name;
+  const char *label;
+  int ret;
+  int sret;
 
   ret = GNUNET_NO;
   if (SQLITE_ROW == (sret = sqlite3_step (stmt)))
   {     
     ret = GNUNET_YES;
-    zone_key =  sqlite3_column_blob (stmt, 0);
-    name = (const char*) sqlite3_column_text (stmt, 1);
-    record_count = sqlite3_column_int (stmt, 2);
-    data_size = sqlite3_column_bytes (stmt, 3);
-    data = sqlite3_column_blob (stmt, 3);
-    expiration.abs_value_us = (uint64_t) sqlite3_column_int64 (stmt, 4);
-    sig = sqlite3_column_blob (stmt, 5);
+    record_count = sqlite3_column_int (stmt, 0);
+    data_size = sqlite3_column_bytes (stmt, 1);
+    data = sqlite3_column_blob (stmt, 1);
+    label = (const char*) sqlite3_column_text (stmt, 2);
 
-    if ( (sizeof (struct GNUNET_CRYPTO_EccPublicKey) != sqlite3_column_bytes 
(stmt, 0)) ||
-        (sizeof (struct GNUNET_CRYPTO_EccSignature) != sqlite3_column_bytes 
(stmt, 5)) )
+    if (record_count > 64 * 1024)
     {
-      GNUNET_break (0);
-      ret = GNUNET_SYSERR;
-    }
-    else if (record_count > 64 * 1024)
-    {
       /* sanity check, don't stack allocate far too much just
         because database might contain a large value here */
       GNUNET_break (0);
@@ -604,8 +722,8 @@
       }
       else
       {
-       iter (iter_cls, zone_key, expiration, name, 
-             record_count, rd, sig);
+       iter (iter_cls, zone_key, label, 
+             record_count, rd);
       }
     }
   }
@@ -613,7 +731,7 @@
   {
     if (SQLITE_DONE != sret)
       LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite_step");
-    iter (iter_cls, NULL, GNUNET_TIME_UNIT_ZERO_ABS, NULL, 0, NULL, NULL);
+    iter (iter_cls, NULL, NULL, 0, NULL);
   }
   if (SQLITE_OK != sqlite3_reset (stmt))
     LOG_SQLITE (plugin,
@@ -621,15 +739,14 @@
                "sqlite3_reset");
   return ret;
 }
-  
-  
+
+
 /**
  * Iterate over the results for a particular key and zone in the
  * datastore.  Will return at most one result to the iterator.
  *
  * @param cls closure (internal context for the plugin)
  * @param zone hash of public key of the zone, NULL to iterate over all zones
- * @param name name as string, NULL to iterate over all records of the zone
  * @param offset offset in the list of all matching records
  * @param iter function to call with the result
  * @param iter_cls closure for iter
@@ -637,38 +754,20 @@
  */
 static int 
 namestore_sqlite_iterate_records (void *cls, 
-                                 const struct GNUNET_CRYPTO_ShortHashCode 
*zone,
-                                 const char *name,
+                                 const struct GNUNET_CRYPTO_EccPrivateKey 
*zone,
                                  uint64_t offset,
                                  GNUNET_NAMESTORE_RecordIterator iter, void 
*iter_cls)
 {
   struct Plugin *plugin = cls;
   sqlite3_stmt *stmt;
-  struct GNUNET_CRYPTO_ShortHashCode name_hase;
-  unsigned int boff;
 
-  if (NULL == zone)
-    if (NULL == name)
-      stmt = plugin->iterate_all;
-    else
-    {
-      GNUNET_CRYPTO_short_hash (name, strlen(name), &name_hase);
-      stmt = plugin->iterate_by_name;
-    }
-  else
-    if (NULL == name)
-      stmt = plugin->iterate_by_zone;
-    else
-    {
-      GNUNET_CRYPTO_short_hash (name, strlen(name), &name_hase);
-      stmt = plugin->iterate_records;
-    }
+  stmt = plugin->iterate_zone;
 
-  boff = 0;
-  if ( (NULL != zone) &&
-       (SQLITE_OK != sqlite3_bind_blob (stmt, ++boff, 
-                                       zone, sizeof (struct 
GNUNET_CRYPTO_ShortHashCode),
-                                       SQLITE_STATIC)) )
+  if ( (SQLITE_OK != sqlite3_bind_blob (stmt, 1, 
+                                       zone, sizeof (struct 
GNUNET_CRYPTO_EccPrivateKey),
+                                       SQLITE_STATIC)) ||
+       (SQLITE_OK != sqlite3_bind_int64 (stmt, 2,
+                                        offset)) ) 
   {
     LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                "sqlite3_bind_XXXX");
@@ -678,36 +777,7 @@
                  "sqlite3_reset");
     return GNUNET_SYSERR;
   }      
-  if ( (NULL != name) &&
-       (SQLITE_OK != sqlite3_bind_blob (stmt, ++boff, 
-                                       &name_hase, sizeof (struct 
GNUNET_CRYPTO_ShortHashCode),
-                                       SQLITE_STATIC)) )
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 
-               "ITERATE NAME HASH: `%8s'", 
-               GNUNET_NAMESTORE_short_h2s(&name_hase));
-    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
-               "sqlite3_bind_XXXX");
-    if (SQLITE_OK != sqlite3_reset (stmt))
-      LOG_SQLITE (plugin,
-                 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
-                 "sqlite3_reset");
-    return GNUNET_SYSERR;
-  }      
-
-  if (SQLITE_OK != sqlite3_bind_int64 (stmt, ++boff, 
-                                      offset)) 
-  {
-    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
-                "sqlite3_bind_XXXX");
-    if (SQLITE_OK != sqlite3_reset (stmt))
-      LOG_SQLITE (plugin,
-                  GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
-                  "sqlite3_reset");
-    return GNUNET_SYSERR;
-  }
-
-  return get_record_and_call_iterator (plugin, stmt, iter, iter_cls);
+  return get_record_and_call_iterator (plugin, stmt, zone, iter, iter_cls);
 }
 
 
@@ -716,16 +786,16 @@
  * Returns at most one result to the iterator.
  *
  * @param cls closure (internal context for the plugin)
- * @param zone hash of public key of the zone to look up in, never NULL
- * @param value_zone hash of the public key of the target zone (value), never 
NULL
+ * @param zone private key of the zone to look up in, never NULL
+ * @param value_zone public key of the target zone (value), never NULL
  * @param iter function to call with the result
  * @param iter_cls closure for iter
  * @return GNUNET_OK on success, GNUNET_NO if there were no results, 
GNUNET_SYSERR on error
  */
 static int
 namestore_sqlite_zone_to_name (void *cls, 
-                              const struct GNUNET_CRYPTO_ShortHashCode *zone,
-                              const struct GNUNET_CRYPTO_ShortHashCode 
*value_zone,
+                              const struct GNUNET_CRYPTO_EccPrivateKey *zone,
+                              const struct GNUNET_CRYPTO_EccPublicKey 
*value_zone,
                               GNUNET_NAMESTORE_RecordIterator iter, void 
*iter_cls)
 {
   struct Plugin *plugin = cls;
@@ -733,10 +803,10 @@
 
   stmt = plugin->zone_to_name;
   if ( (SQLITE_OK != sqlite3_bind_blob (stmt, 1, 
-                                       zone, sizeof (struct 
GNUNET_CRYPTO_ShortHashCode),
+                                       zone, sizeof (struct 
GNUNET_CRYPTO_EccPrivateKey),
                                        SQLITE_STATIC)) ||
        (SQLITE_OK != sqlite3_bind_blob (stmt, 2, 
-                                       value_zone, sizeof (struct 
GNUNET_CRYPTO_ShortHashCode),
+                                       value_zone, sizeof (struct 
GNUNET_CRYPTO_EccPublicKey),
                                        SQLITE_STATIC)) )
   {
     LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
@@ -747,56 +817,11 @@
                  "sqlite3_reset");
     return GNUNET_SYSERR;
   }      
-  return get_record_and_call_iterator (plugin, stmt, iter, iter_cls);
+  return get_record_and_call_iterator (plugin, stmt, zone, iter, iter_cls);
 }
 
 
 /**
- * Delete an entire zone (all records).  Not used in normal operation.
- *
- * @param cls closure (internal context for the plugin)
- * @param zone zone to delete
- */
-static void 
-namestore_sqlite_delete_zone (void *cls,
-                             const struct GNUNET_CRYPTO_ShortHashCode *zone)
-{
-  struct Plugin *plugin = cls;
-  sqlite3_stmt *stmt = plugin->delete_zone;
-  int n;
-
-  if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, zone, sizeof (struct 
GNUNET_CRYPTO_ShortHashCode), SQLITE_STATIC))
-  {
-    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
-                "sqlite3_bind_XXXX");
-    if (SQLITE_OK != sqlite3_reset (stmt))
-      LOG_SQLITE (plugin,
-                  GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
-                  "sqlite3_reset");
-    return;
-  }
-  n = sqlite3_step (stmt);
-  if (SQLITE_OK != sqlite3_reset (stmt))
-    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
-               "sqlite3_reset");
-  switch (n)
-  {
-  case SQLITE_DONE:
-    GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Values deleted\n");
-    break;
-  case SQLITE_BUSY:
-    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK,
-               "sqlite3_step");
-    break;
-  default:
-    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
-               "sqlite3_step");
-    break;
-  }
-}
-
-
-/**
  * Entry point for the plugin.
  *
  * @param cls the "struct GNUNET_NAMESTORE_PluginEnvironment*"
@@ -818,13 +843,13 @@
     database_shutdown (&plugin);
     return NULL;
   }
-  api = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_PluginFunctions));
+  api = GNUNET_new (struct GNUNET_NAMESTORE_PluginFunctions);
   api->cls = &plugin;
-  api->put_records = &namestore_sqlite_put_records;
-  api->remove_records = &namestore_sqlite_remove_records;
+  api->cache_block = &namestore_sqlite_cache_block;
+  api->lookup_block = &namestore_sqlite_lookup_block;
+  api->store_records = &namestore_sqlite_store_records;
   api->iterate_records = &namestore_sqlite_iterate_records;
   api->zone_to_name = &namestore_sqlite_zone_to_name;
-  api->delete_zone = &namestore_sqlite_delete_zone;
   LOG (GNUNET_ERROR_TYPE_INFO, 
        _("Sqlite database running\n"));
   return api;




reply via email to

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