aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2013-08-12 19:09:52 +0000
committerChristian Grothoff <christian@grothoff.org>2013-08-12 19:09:52 +0000
commit5e05019536c0d38bf20f965613636f21ae7c2be6 (patch)
treeeda1dee12e49c010171462d618162d28b21c9c6a
parent566dfe32be22ed1f071b974be3c4dd8bc5721151 (diff)
downloadgnunet-5e05019536c0d38bf20f965613636f21ae7c2be6.tar.gz
gnunet-5e05019536c0d38bf20f965613636f21ae7c2be6.zip
-towards namestore support for the new privacy-preserving GNS queries
-rw-r--r--src/Makefile.am12
-rw-r--r--src/include/gnunet_namestore_plugin.h114
-rw-r--r--src/include/gnunet_namestore_service.h313
-rw-r--r--src/include/gnunet_protocols.h34
-rw-r--r--src/namestore/Makefile.am5
-rw-r--r--src/namestore/gnunet-namestore.c160
-rw-r--r--src/namestore/namestore.h261
-rw-r--r--src/namestore/namestore_api.c607
-rw-r--r--src/namestore/namestore_api_common.c225
-rw-r--r--src/namestore/namestore_api_monitor.c35
-rw-r--r--src/namestore/plugin_namestore_sqlite.c595
11 files changed, 1155 insertions, 1206 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 00c4d6f93..d8d3fbf57 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -10,15 +10,17 @@ if HAVE_TESTING
10endif 10endif
11 11
12if HAVE_EXPERIMENTAL 12if HAVE_EXPERIMENTAL
13 EXP_DIR = dv $(CONSENSUS) $(EXPERIMENTATION) 13 EXP_DIR = dv $(CONSENSUS) $(EXPERIMENTATION)
14endif 14endif
15 15
16if LINUX 16if LINUX
17# All of these currently only work on GNU/Linux or W32 17# All of these currently only work on GNU/Linux or W32
18 LINUX_DIR = exit vpn pt 18 LINUX_DIR = exit vpn
19# pt # without namestore, pt currently has some issues...
19endif 20endif
20if MINGW 21if MINGW
21 MINGW_DIR = vpn exit pt 22 MINGW_DIR = vpn exit
23# pt # without namestore, pt currently has some issues...
22endif 24endif
23 25
24if HAVE_MYSQL 26if HAVE_MYSQL
@@ -44,7 +46,6 @@ SUBDIRS = \
44 $(POSTGRES_DIR) \ 46 $(POSTGRES_DIR) \
45 datacache \ 47 datacache \
46 datastore \ 48 datastore \
47 namestore \
48 template \ 49 template \
49 ats \ 50 ats \
50 nat \ 51 nat \
@@ -67,6 +68,7 @@ SUBDIRS = \
67 fs \ 68 fs \
68 $(LINUX_DIR) \ 69 $(LINUX_DIR) \
69 $(MINGW_DIR) \ 70 $(MINGW_DIR) \
70 gns \
71 integration-tests \ 71 integration-tests \
72 $(EXP_DIR) 72 $(EXP_DIR)
73
74# note: namestore, gns are not listed right now as they are being reworked to use the new crypto \ No newline at end of file
diff --git a/src/include/gnunet_namestore_plugin.h b/src/include/gnunet_namestore_plugin.h
index b4ffc257d..6ac0038ba 100644
--- a/src/include/gnunet_namestore_plugin.h
+++ b/src/include/gnunet_namestore_plugin.h
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet 2 This file is part of GNUnet
3 (C) 2012 Christian Grothoff (and other contributing authors) 3 (C) 2012, 2013 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -40,25 +40,29 @@ extern "C"
40 40
41 41
42/** 42/**
43 * Function called for matching blocks.
44 *
45 * @param cls closure
46 * @param block lookup result
47 */
48typedef void (*GNUNET_NAMESTORE_BlockCallback) (void *cls,
49 const struct GNUNET_NAMESTORE_Block *block);
50
51
52/**
43 * Function called by for each matching record. 53 * Function called by for each matching record.
44 * 54 *
45 * @param cls closure 55 * @param cls closure
46 * @param zone_key public key of the zone 56 * @param zone_key private key of the zone
47 * @param expire when does the corresponding block in the DHT expire (until 57 * @param label name that is being mapped (at most 255 characters long)
48 * when should we never do a DHT lookup for the same name again)?
49 * @param name name that is being mapped (at most 255 characters long)
50 * @param rd_count number of entries in 'rd' array 58 * @param rd_count number of entries in 'rd' array
51 * @param rd array of records with data to store 59 * @param rd array of records with data to store
52 * @param signature signature of the record block, NULL if signature is unavailable (i.e.
53 * because the user queried for a particular record type only)
54 */ 60 */
55typedef void (*GNUNET_NAMESTORE_RecordIterator) (void *cls, 61typedef void (*GNUNET_NAMESTORE_RecordIterator) (void *cls,
56 const struct GNUNET_CRYPTO_EccPublicKey *zone_key, 62 const struct GNUNET_CRYPTO_EccPrivateKey *private_key,
57 struct GNUNET_TIME_Absolute expire, 63 const char *label,
58 const char *name, 64 unsigned int rd_count,
59 unsigned int rd_len, 65 const struct GNUNET_NAMESTORE_RecordData *rd);
60 const struct GNUNET_NAMESTORE_RecordData *rd,
61 const struct GNUNET_CRYPTO_EccSignature *signature);
62 66
63 67
64/** 68/**
@@ -73,49 +77,58 @@ struct GNUNET_NAMESTORE_PluginFunctions
73 void *cls; 77 void *cls;
74 78
75 /** 79 /**
76 * Store a record in the datastore. Removes any existing record in the 80 * Cache a block in the datastore. Overwrites (older) existing blocks
77 * same zone with the same name. 81 * for the same zone and label.
78 * 82 *
79 * @param cls closure (internal context for the plugin) 83 * @param cls closure (internal context for the plugin)
80 * @param zone_key public key of the zone 84 * @param block block to cache
81 * @param expire when does the corresponding block in the DHT expire (until
82 * when should we never do a DHT lookup for the same name again)?
83 * @param name name that is being mapped (at most 255 characters long)
84 * @param rd_count number of entries in 'rd' array
85 * @param rd array of records with data to store
86 * @param signature signature of the record block, NULL if signature is unavailable (i.e.
87 * because the user queried for a particular record type only)
88 * @return GNUNET_OK on success, else GNUNET_SYSERR 85 * @return GNUNET_OK on success, else GNUNET_SYSERR
89 */ 86 */
90 int (*put_records) (void *cls, 87 int (*cache_block) (void *cls,
91 const struct GNUNET_CRYPTO_EccPublicKey *zone_key, 88 const struct GNUNET_NAMESTORE_Block *block);
92 struct GNUNET_TIME_Absolute expire, 89
93 const char *name, 90
94 unsigned int rd_len, 91 /**
95 const struct GNUNET_NAMESTORE_RecordData *rd, 92 * Get the block for a particular zone and label in the
96 const struct GNUNET_CRYPTO_EccSignature *signature); 93 * datastore. Will return at most one result to the iterator.
94 *
95 * @param cls closure (internal context for the plugin)
96 * @param query hash of public key derived from the zone and the label
97 * @param iter function to call with the result
98 * @param iter_cls closure for iter
99 * @return GNUNET_OK on success, GNUNET_NO if there were no results, GNUNET_SYSERR on error
100 * 'iter' will have been called unless the return value is 'GNUNET_SYSERR'
101 */
102 int (*lookup_block) (void *cls,
103 const struct GNUNET_HashCode *query,
104 GNUNET_NAMESTORE_BlockCallback iter, void *iter_cls);
105
97 106
98 107
99 /** 108 /**
100 * Removes any existing record in the given zone with the same name. 109 * Store a record in the datastore for which we are the authority.
110 * Removes any existing record in the same zone with the same name.
101 * 111 *
102 * @param cls closure (internal context for the plugin) 112 * @param cls closure (internal context for the plugin)
103 * @param zone hash of the public key of the zone 113 * @param zone private key of the zone
104 * @param name name to remove (at most 255 characters long) 114 * @param label name of the record in the zone
105 * @return GNUNET_OK on success 115 * @param rd_count number of entries in 'rd' array, 0 to delete all records
116 * @param rd array of records with data to store
117 * @return GNUNET_OK on success, else GNUNET_SYSERR
106 */ 118 */
107 int (*remove_records) (void *cls, 119 int (*store_records) (void *cls,
108 const struct GNUNET_CRYPTO_ShortHashCode *zone, 120 const struct GNUNET_CRYPTO_EccPrivateKey *zone,
109 const char *name); 121 const char *label,
122 unsigned int rd_count,
123 const struct GNUNET_NAMESTORE_RecordData *rd);
110 124
111 125
112 /** 126 /**
113 * Iterate over the results for a particular key and zone in the 127 * Iterate over the results for a particular zone in the
114 * datastore. Will return at most one result to the iterator. 128 * datastore. Will return at most one result to the iterator.
115 * 129 *
116 * @param cls closure (internal context for the plugin) 130 * @param cls closure (internal context for the plugin)
117 * @param zone hash of public key of the zone, NULL to iterate over all zones 131 * @param zone private key of the zone
118 * @param name name as '\0' terminated string, NULL to iterate over all records of the zone
119 * @param offset offset in the list of all matching records 132 * @param offset offset in the list of all matching records
120 * @param iter function to call with the result 133 * @param iter function to call with the result
121 * @param iter_cls closure for iter 134 * @param iter_cls closure for iter
@@ -123,8 +136,7 @@ struct GNUNET_NAMESTORE_PluginFunctions
123 * 'iter' will have been called unless the return value is 'GNUNET_SYSERR' 136 * 'iter' will have been called unless the return value is 'GNUNET_SYSERR'
124 */ 137 */
125 int (*iterate_records) (void *cls, 138 int (*iterate_records) (void *cls,
126 const struct GNUNET_CRYPTO_ShortHashCode *zone, 139 const struct GNUNET_CRYPTO_EccPrivateKey *zone,
127 const char *name,
128 uint64_t offset, 140 uint64_t offset,
129 GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls); 141 GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls);
130 142
@@ -134,29 +146,19 @@ struct GNUNET_NAMESTORE_PluginFunctions
134 * Returns at most one result to the iterator. 146 * Returns at most one result to the iterator.
135 * 147 *
136 * @param cls closure (internal context for the plugin) 148 * @param cls closure (internal context for the plugin)
137 * @param zone hash of public key of the zone to look up in, never NULL 149 * @param zone private key of the zone to look up in, never NULL
138 * @param value_zone hash of the public key of the target zone (value), never NULL 150 * @param value_zone public key of the target zone (value), never NULL
139 * @param iter function to call with the result 151 * @param iter function to call with the result
140 * @param iter_cls closure for iter 152 * @param iter_cls closure for iter
141 * @return GNUNET_OK on success, GNUNET_NO if there were no results, GNUNET_SYSERR on error 153 * @return GNUNET_OK on success, GNUNET_NO if there were no results, GNUNET_SYSERR on error
142 * 'iter' will have been called unless the return value is 'GNUNET_SYSERR' 154 * 'iter' will have been called unless the return value is 'GNUNET_SYSERR'
143 */ 155 */
144 int (*zone_to_name) (void *cls, 156 int (*zone_to_name) (void *cls,
145 const struct GNUNET_CRYPTO_ShortHashCode *zone, 157 const struct GNUNET_CRYPTO_EccPrivateKey *zone,
146 const struct GNUNET_CRYPTO_ShortHashCode *value_zone, 158 const struct GNUNET_CRYPTO_EccPublicKey *value_zone,
147 GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls); 159 GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls);
148 160
149 161
150 /**
151 * Delete an entire zone (all records). Not used in normal operation.
152 *
153 * @param cls closure (internal context for the plugin)
154 * @param zone zone to delete
155 */
156 void (*delete_zone) (void *cls,
157 const struct GNUNET_CRYPTO_ShortHashCode *zone);
158
159
160}; 162};
161 163
162 164
diff --git a/src/include/gnunet_namestore_service.h b/src/include/gnunet_namestore_service.h
index 77da67312..db7453063 100644
--- a/src/include/gnunet_namestore_service.h
+++ b/src/include/gnunet_namestore_service.h
@@ -21,12 +21,11 @@
21/** 21/**
22 * @file include/gnunet_namestore_service.h 22 * @file include/gnunet_namestore_service.h
23 * @brief API that can be used to store naming information on a GNUnet node; 23 * @brief API that can be used to store naming information on a GNUnet node;
24 * Naming information can either be records for which this peer/user
25 * is authoritative, or blocks which are cached, encrypted naming
26 * data from other peers.
24 * @author Christian Grothoff 27 * @author Christian Grothoff
25 *
26 * Other functions we might want:
27 * - enumerate all known zones
28 */ 28 */
29
30#ifndef GNUNET_NAMESTORE_SERVICE_H 29#ifndef GNUNET_NAMESTORE_SERVICE_H
31#define GNUNET_NAMESTORE_SERVICE_H 30#define GNUNET_NAMESTORE_SERVICE_H
32 31
@@ -97,7 +96,6 @@ struct GNUNET_NAMESTORE_ZoneIterator;
97#define GNUNET_NAMESTORE_MAX_VALUE_SIZE (63 * 1024) 96#define GNUNET_NAMESTORE_MAX_VALUE_SIZE (63 * 1024)
98 97
99 98
100
101/** 99/**
102 * Connect to the namestore service. 100 * Connect to the namestore service.
103 * 101 *
@@ -229,53 +227,51 @@ struct GNUNET_NAMESTORE_RecordData
229 227
230 228
231/** 229/**
230 * Information we have in an encrypted block with record data (i.e. in the DHT).
231 */
232struct GNUNET_NAMESTORE_Block
233{
234
235 /**
236 * Signature of the block.
237 */
238 struct GNUNET_CRYPTO_EccSignature signature;
239
240 /**
241 * Derived key used for signing; hash of this is the query.
242 */
243 struct GNUNET_CRYPTO_EccPublicKey derived_key;
244
245 /**
246 * Number of bytes signed; also specifies the number of bytes
247 * of encrypted data that follow.
248 */
249 struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
250
251 /**
252 * Expiration time of the block.
253 */
254 struct GNUNET_TIME_AbsoluteNBO expiration_time;
255
256 /* followed by encrypted data */
257};
258
259
260/**
232 * Store an item in the namestore. If the item is already present, 261 * Store an item in the namestore. If the item is already present,
233 * it is replaced with the new record. Use an empty array to 262 * it is replaced with the new record.
234 * remove all records under the given name.
235 * 263 *
236 * @param h handle to the namestore 264 * @param h handle to the namestore
237 * @param zone_key public key of the zone 265 * @param block block to store
238 * @param name name that is being mapped (at most 255 characters long)
239 * @param freshness when does the corresponding block in the DHT expire (until
240 * when should we never do a DHT lookup for the same name again)?
241 * @param rd_count number of entries in 'rd' array
242 * @param rd array of records with data to store
243 * @param signature signature for all the records in the zone under the given name
244 * @param cont continuation to call when done 266 * @param cont continuation to call when done
245 * @param cont_cls closure for cont 267 * @param cont_cls closure for cont
246 * @return handle to abort the request 268 * @return handle to abort the request
247 */ 269 */
248struct GNUNET_NAMESTORE_QueueEntry * 270struct GNUNET_NAMESTORE_QueueEntry *
249GNUNET_NAMESTORE_record_put (struct GNUNET_NAMESTORE_Handle *h, 271GNUNET_NAMESTORE_block_cache (struct GNUNET_NAMESTORE_Handle *h,
250 const struct GNUNET_CRYPTO_EccPublicKey *zone_key, 272 const struct GNUNET_NAMESTORE_Block *block,
251 const char *name, 273 GNUNET_NAMESTORE_ContinuationWithStatus cont,
252 struct GNUNET_TIME_Absolute freshness, 274 void *cont_cls);
253 unsigned int rd_count,
254 const struct GNUNET_NAMESTORE_RecordData *rd,
255 const struct GNUNET_CRYPTO_EccSignature *signature,
256 GNUNET_NAMESTORE_ContinuationWithStatus cont,
257 void *cont_cls);
258
259
260/**
261 * Check if a signature is valid. This API is used by the GNS Block
262 * to validate signatures received from the network.
263 *
264 * @param public_key public key of the zone
265 * @param freshness time set for block expiration
266 * @param name name that is being mapped (at most 255 characters long)
267 * @param rd_count number of entries in 'rd' array
268 * @param rd array of records with data to store
269 * @param signature signature for all the records in the zone under the given name
270 * @return GNUNET_OK if the signature is valid
271 */
272int
273GNUNET_NAMESTORE_verify_signature (const struct GNUNET_CRYPTO_EccPublicKey *public_key,
274 const struct GNUNET_TIME_Absolute freshness,
275 const char *name,
276 unsigned int rd_count,
277 const struct GNUNET_NAMESTORE_RecordData *rd,
278 const struct GNUNET_CRYPTO_EccSignature *signature);
279 275
280 276
281/** 277/**
@@ -285,7 +281,7 @@ GNUNET_NAMESTORE_verify_signature (const struct GNUNET_CRYPTO_EccPublicKey *publ
285 * 281 *
286 * @param h handle to the namestore 282 * @param h handle to the namestore
287 * @param pkey private key of the zone 283 * @param pkey private key of the zone
288 * @param name name that is being mapped (at most 255 characters long) 284 * @param label name that is being mapped (at most 255 characters long)
289 * @param rd_count number of records in the 'rd' array 285 * @param rd_count number of records in the 'rd' array
290 * @param rd array of records with data to store 286 * @param rd array of records with data to store
291 * @param cont continuation to call when done 287 * @param cont continuation to call when done
@@ -293,67 +289,56 @@ GNUNET_NAMESTORE_verify_signature (const struct GNUNET_CRYPTO_EccPublicKey *publ
293 * @return handle to abort the request 289 * @return handle to abort the request
294 */ 290 */
295struct GNUNET_NAMESTORE_QueueEntry * 291struct GNUNET_NAMESTORE_QueueEntry *
296GNUNET_NAMESTORE_record_put_by_authority (struct GNUNET_NAMESTORE_Handle *h, 292GNUNET_NAMESTORE_records_store (struct GNUNET_NAMESTORE_Handle *h,
297 const struct GNUNET_CRYPTO_EccPrivateKey *pkey, 293 const struct GNUNET_CRYPTO_EccPrivateKey *pkey,
298 const char *name, 294 const char *label,
299 unsigned int rd_count, 295 unsigned int rd_count,
300 const struct GNUNET_NAMESTORE_RecordData *rd, 296 const struct GNUNET_NAMESTORE_RecordData *rd,
301 GNUNET_NAMESTORE_ContinuationWithStatus cont, 297 GNUNET_NAMESTORE_ContinuationWithStatus cont,
302 void *cont_cls); 298 void *cont_cls);
303 299
304 300
305/** 301/**
306 * Process a record that was stored in the namestore. 302 * Process a record that was stored in the namestore.
307 * 303 *
308 * @param cls closure 304 * @param cls closure
309 * @param zone_key public key of the zone 305 * @param block block that was stored in the namestore
310 * @param freshness when does the corresponding block in the DHT expire (until
311 * when should we never do a DHT lookup for the same name again)?;
312 * GNUNET_TIME_UNIT_ZERO_ABS if there are no records of any type in the namestore,
313 * or the expiration time of the block in the namestore (even if there are zero
314 * records matching the desired record type)
315 * @param name name that is being mapped (at most 255 characters long)
316 * @param rd_count number of entries in 'rd' array
317 * @param rd array of records with data to store
318 * @param signature signature of the record block, NULL if signature is unavailable (i.e.
319 * because the user queried for a particular record type only)
320 */ 306 */
321typedef void (*GNUNET_NAMESTORE_RecordProcessor) (void *cls, 307typedef void (*GNUNET_NAMESTORE_BlockProcessor) (void *cls,
322 const struct GNUNET_CRYPTO_EccPublicKey *zone_key, 308 const struct GNUNET_NAMESTORE_Block *block);
323 struct GNUNET_TIME_Absolute freshness,
324 const char *name,
325 unsigned int rd_count,
326 const struct GNUNET_NAMESTORE_RecordData *rd,
327 const struct GNUNET_CRYPTO_EccSignature *signature);
328 309
329 310
330/** 311/**
331 * Get a result for a particular key from the namestore. The processor 312 * Get a result for a particular key from the namestore. The processor
332 * will only be called once. When using this functions, relative expiration 313 * will only be called once.
333 * times will be converted to absolute expiration times and a signature
334 * will be created if we are the authority. The record data and signature
335 * passed to 'proc' is thus always suitable for passing on to other peers
336 * (if we are the authority). If the record type is NOT set to 'ANY' and
337 * if we are NOT the authority, then non-matching records may be omitted
338 * from the result and no valid signature can be created; in this case,
339 * 'signature' will be NULL and the result cannot be given to other peers.
340 * 314 *
341 * @param h handle to the namestore 315 * @param h handle to the namestore
342 * @param zone zone to look up a record from 316 * @param derived_hash hash of zone key combined with name to lookup
343 * @param name name to look up 317 * @param proc function to call on the matching block, or with
344 * @param record_type desired record type, 0 for all 318 * NULL if there is no matching block
345 * @param proc function to call on the matching records, or with
346 * NULL (rd_count == 0) if there are no matching records
347 * @param proc_cls closure for proc 319 * @param proc_cls closure for proc
348 * @return a handle that can be used to 320 * @return a handle that can be used to cancel
349 * cancel
350 */ 321 */
351struct GNUNET_NAMESTORE_QueueEntry * 322struct GNUNET_NAMESTORE_QueueEntry *
352GNUNET_NAMESTORE_lookup_record (struct GNUNET_NAMESTORE_Handle *h, 323GNUNET_NAMESTORE_lookup_block (struct GNUNET_NAMESTORE_Handle *h,
353 const struct GNUNET_CRYPTO_ShortHashCode *zone, 324 const struct GNUNET_HashCode *derived_hash,
354 const char *name, 325 GNUNET_NAMESTORE_BlockProcessor proc, void *proc_cls);
355 uint32_t record_type, 326
356 GNUNET_NAMESTORE_RecordProcessor proc, void *proc_cls); 327
328/**
329 * Process a record that was stored in the namestore.
330 *
331 * @param cls closure
332 * @param zone private key of the zone
333 * @param label label of the records
334 * @param rd_count number of entries in 'rd' array
335 * @param rd array of records with data to store
336 */
337typedef void (*GNUNET_NAMESTORE_RecordMonitor) (void *cls,
338 const struct GNUNET_CRYPTO_EccPrivateKey *zone,
339 const char *label,
340 unsigned int rd_count,
341 const struct GNUNET_NAMESTORE_RecordData *rd);
357 342
358 343
359/** 344/**
@@ -361,8 +346,8 @@ GNUNET_NAMESTORE_lookup_record (struct GNUNET_NAMESTORE_Handle *h,
361 * Returns at most one result to the processor. 346 * Returns at most one result to the processor.
362 * 347 *
363 * @param h handle to the namestore 348 * @param h handle to the namestore
364 * @param zone hash of public key of the zone to look up in, never NULL 349 * @param zone public key of the zone to look up in, never NULL
365 * @param value_zone hash of the public key of the target zone (value), never NULL 350 * @param value_zone public key of the target zone (value), never NULL
366 * @param proc function to call on the matching records, or with 351 * @param proc function to call on the matching records, or with
367 * NULL (rd_count == 0) if there are no matching records 352 * NULL (rd_count == 0) if there are no matching records
368 * @param proc_cls closure for proc 353 * @param proc_cls closure for proc
@@ -371,9 +356,9 @@ GNUNET_NAMESTORE_lookup_record (struct GNUNET_NAMESTORE_Handle *h,
371 */ 356 */
372struct GNUNET_NAMESTORE_QueueEntry * 357struct GNUNET_NAMESTORE_QueueEntry *
373GNUNET_NAMESTORE_zone_to_name (struct GNUNET_NAMESTORE_Handle *h, 358GNUNET_NAMESTORE_zone_to_name (struct GNUNET_NAMESTORE_Handle *h,
374 const struct GNUNET_CRYPTO_ShortHashCode *zone, 359 const struct GNUNET_CRYPTO_EccPrivateKey *zone,
375 const struct GNUNET_CRYPTO_ShortHashCode *value_zone, 360 const struct GNUNET_CRYPTO_EccPublicKey *value_zone,
376 GNUNET_NAMESTORE_RecordProcessor proc, void *proc_cls); 361 GNUNET_NAMESTORE_RecordMonitor proc, void *proc_cls);
377 362
378 363
379/** 364/**
@@ -393,28 +378,8 @@ GNUNET_NAMESTORE_cancel (struct GNUNET_NAMESTORE_QueueEntry *qe);
393 * records into our DHT). "proc" will be called once immediately, and 378 * records into our DHT). "proc" will be called once immediately, and
394 * then again after "GNUNET_NAMESTORE_zone_iterator_next" is invoked. 379 * then again after "GNUNET_NAMESTORE_zone_iterator_next" is invoked.
395 * 380 *
396 * By specifying a 'zone' of NULL and setting 'GNUNET_NAMESTORE_RF_AUTHORITY'
397 * in 'must_have_flags', we can iterate over all records for which we are
398 * the authority (the 'authority' flag will NOT be set in the returned
399 * records anyway).
400 *
401 * The 'GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION'
402 * bit in 'must_have_flags' has a special meaning:
403 *
404 * 0) If the bit is clear, all relative expriation times are converted to
405 * absolute expiration times. This is useful for performing DHT PUT
406 * operations (and zone transfers) of our zone. The generated signatures
407 * will be valid for other peers.
408 * 1) if it is set, it means that relative expiration times should be
409 * preserved when returned (this is useful for the zone editor user
410 * interface). No signatures will be created in this case, as
411 * signatures must not cover records with relative expiration times.
412 *
413 * Note that not all queries against this interface are equally performant
414 * as for some combinations no efficient index may exist.
415 *
416 * @param h handle to the namestore 381 * @param h handle to the namestore
417 * @param zone zone to access, NULL for all zones 382 * @param zone zone to access
418 * @param must_have_flags flags that must be set for the record to be returned 383 * @param must_have_flags flags that must be set for the record to be returned
419 * @param must_not_have_flags flags that must NOT be set for the record to be returned 384 * @param must_not_have_flags flags that must NOT be set for the record to be returned
420 * @param proc function to call on each name from the zone; it 385 * @param proc function to call on each name from the zone; it
@@ -425,10 +390,8 @@ GNUNET_NAMESTORE_cancel (struct GNUNET_NAMESTORE_QueueEntry *qe);
425 */ 390 */
426struct GNUNET_NAMESTORE_ZoneIterator * 391struct GNUNET_NAMESTORE_ZoneIterator *
427GNUNET_NAMESTORE_zone_iteration_start (struct GNUNET_NAMESTORE_Handle *h, 392GNUNET_NAMESTORE_zone_iteration_start (struct GNUNET_NAMESTORE_Handle *h,
428 const struct GNUNET_CRYPTO_ShortHashCode *zone, 393 const struct GNUNET_CRYPTO_EccPrivateKey *zone,
429 enum GNUNET_NAMESTORE_RecordFlags must_have_flags, 394 GNUNET_NAMESTORE_RecordMonitor proc,
430 enum GNUNET_NAMESTORE_RecordFlags must_not_have_flags,
431 GNUNET_NAMESTORE_RecordProcessor proc,
432 void *proc_cls); 395 void *proc_cls);
433 396
434 397
@@ -460,35 +423,6 @@ struct GNUNET_NAMESTORE_ZoneMonitor;
460 423
461 424
462/** 425/**
463 * Function called whenever the records for a given name changed.
464 *
465 * @param cls closure
466 * @param zone_key NULL if the communication with the namestore broke down
467 * (and thus all entries should be 'cleared' until the communication
468 * can be re-established, at which point the monitor will
469 * re-add all records that are (still) in the namestore after
470 * the reconnect); if this value is NULL, all other arguments
471 * will also be 0/NULL.
472 * @param freshness when does the corresponding block in the DHT expire (until
473 * when should we never do a DHT lookup for the same name again)?;
474 * GNUNET_TIME_UNIT_ZERO_ABS if there are no records of any type in the namestore,
475 * or the expiration time of the block in the namestore (even if there are zero
476 * records matching the desired record type)
477 * @param name name that is being mapped (at most 255 characters long)
478 * @param rd_count number of entries in 'rd' array
479 * @param rd array of records with data to store
480 * @param signature signature of the record block
481 */
482typedef void (*GNUNET_NAMESTORE_RecordMonitor)(void *cls,
483 const struct GNUNET_CRYPTO_EccPublicKey *zone_key,
484 struct GNUNET_TIME_Absolute freshness,
485 const char *name,
486 unsigned int rd_len,
487 const struct GNUNET_NAMESTORE_RecordData *rd,
488 const struct GNUNET_CRYPTO_EccSignature *signature);
489
490
491/**
492 * Function called once the monitor has caught up with the current 426 * Function called once the monitor has caught up with the current
493 * state of the database. Will be called AGAIN after each disconnect 427 * state of the database. Will be called AGAIN after each disconnect
494 * (record monitor called with 'NULL' for zone_key) once we're again 428 * (record monitor called with 'NULL' for zone_key) once we're again
@@ -513,7 +447,7 @@ typedef void (*GNUNET_NAMESTORE_RecordsSynchronizedCallback)(void *cls);
513 * monitoring). 447 * monitoring).
514 * 448 *
515 * @param cfg configuration to use to connect to namestore 449 * @param cfg configuration to use to connect to namestore
516 * @param zone zone to monitor, NULL for all zones 450 * @param zone zone to monitor
517 * @param monitor function to call on zone changes 451 * @param monitor function to call on zone changes
518 * @param sync_cb function called when we're in sync with the namestore 452 * @param sync_cb function called when we're in sync with the namestore
519 * @param cls closure for 'monitor' and 'sync_cb' 453 * @param cls closure for 'monitor' and 'sync_cb'
@@ -521,7 +455,7 @@ typedef void (*GNUNET_NAMESTORE_RecordsSynchronizedCallback)(void *cls);
521 */ 455 */
522struct GNUNET_NAMESTORE_ZoneMonitor * 456struct GNUNET_NAMESTORE_ZoneMonitor *
523GNUNET_NAMESTORE_zone_monitor_start (const struct GNUNET_CONFIGURATION_Handle *cfg, 457GNUNET_NAMESTORE_zone_monitor_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
524 const struct GNUNET_CRYPTO_ShortHashCode *zone, 458 const struct GNUNET_CRYPTO_EccPrivateKey *zone,
525 GNUNET_NAMESTORE_RecordMonitor monitor, 459 GNUNET_NAMESTORE_RecordMonitor monitor,
526 GNUNET_NAMESTORE_RecordsSynchronizedCallback sync_cb, 460 GNUNET_NAMESTORE_RecordsSynchronizedCallback sync_cb,
527 void *cls); 461 void *cls);
@@ -659,15 +593,41 @@ GNUNET_NAMESTORE_normalize_string (const char *src);
659 593
660 594
661/** 595/**
662 * Convert a short hash to a string (for printing debug messages). 596 * Convert a zone to a string (for printing debug messages).
663 * This is one of the very few calls in the entire API that is 597 * This is one of the very few calls in the entire API that is
664 * NOT reentrant! 598 * NOT reentrant!
665 * 599 *
666 * @param hc the short hash code 600 * @param z public key of a zone
667 * @return string form; will be overwritten by next call to GNUNET_h2s. 601 * @return string form; will be overwritten by next call to GNUNET_h2s.
668 */ 602 */
669const char * 603const char *
670GNUNET_NAMESTORE_short_h2s (const struct GNUNET_CRYPTO_ShortHashCode * hc); 604GNUNET_NAMESTORE_z2s (const struct GNUNET_CRYPTO_EccPublicKey *z);
605
606
607/**
608 * Calculate the DHT query for a given 'label' in a given zone.
609 *
610 * @param zone private key of the zone
611 * @param label label of the record
612 * @return query hash to use for the query
613 */
614void
615GNUNET_NAMESTORE_query_from_private_key (const struct GNUNET_CRYPTO_EccPrivateKey *zone,
616 const char *label,
617 struct GNUNET_HashCode *query);
618
619
620/**
621 * Calculate the DHT query for a given 'label' in a given zone.
622 *
623 * @param pub public key of the zone
624 * @param label label of the record
625 * @return query hash to use for the query
626 */
627void
628GNUNET_NAMESTORE_query_from_public_key (const struct GNUNET_CRYPTO_EccPublicKey *pub,
629 const char *label,
630 struct GNUNET_HashCode *query);
671 631
672 632
673/** 633/**
@@ -675,18 +635,47 @@ GNUNET_NAMESTORE_short_h2s (const struct GNUNET_CRYPTO_ShortHashCode * hc);
675 * 635 *
676 * @param key the private key 636 * @param key the private key
677 * @param expire block expiration 637 * @param expire block expiration
678 * @param name the name 638 * @param label the name for the records
679 * @param rd record data 639 * @param rd record data
680 * @param rd_count number of records 640 * @param rd_count number of records
641 * @param signature where to store the signature
642 */
643struct GNUNET_NAMESTORE_Block *
644GNUNET_NAMESTORE_block_create (const struct GNUNET_CRYPTO_EccPrivateKey *key,
645 struct GNUNET_TIME_Absolute expire,
646 const char *label,
647 const struct GNUNET_NAMESTORE_RecordData *rd,
648 unsigned int rd_count);
649
650
651/**
652 * Check if a signature is valid. This API is used by the GNS Block
653 * to validate signatures received from the network.
681 * 654 *
682 * @return the signature 655 * @param block block to verify
656 * @return GNUNET_OK if the signature is valid
683 */ 657 */
684struct GNUNET_CRYPTO_EccSignature * 658int
685GNUNET_NAMESTORE_create_signature (const struct GNUNET_CRYPTO_EccPrivateKey *key, 659GNUNET_NAMESTORE_block_verify (const struct GNUNET_NAMESTORE_Block *block);
686 struct GNUNET_TIME_Absolute expire, 660
687 const char *name, 661
688 const struct GNUNET_NAMESTORE_RecordData *rd, 662/**
689 unsigned int rd_count); 663 * Decrypt block.
664 *
665 * @param block block to decrypt
666 * @param zone_key public key of the zone
667 * @param label the name for the records
668 * @param proc function to call with the result
669 * @param proc_cls closure for proc
670 * @param GNUNET_OK on success, GNUNET_SYSERR if the block was
671 * not well-formed
672 */
673int
674GNUNET_NAMESTORE_block_decrypt (const struct GNUNET_NAMESTORE_Block *block,
675 const struct GNUNET_CRYPTO_EccPublicKey *zone_key,
676 const char *label,
677 GNUNET_NAMESTORE_RecordMonitor proc,
678 void *proc_cls);
690 679
691 680
692/** 681/**
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h
index 06703abe9..5c59f36f4 100644
--- a/src/include/gnunet_protocols.h
+++ b/src/include/gnunet_protocols.h
@@ -1331,39 +1331,34 @@ extern "C"
1331 ******************************************************************************/ 1331 ******************************************************************************/
1332 1332
1333/** 1333/**
1334 * Client to service: register. 1334 * Client to service: lookup block
1335 */ 1335 */
1336#define GNUNET_MESSAGE_TYPE_NAMESTORE_START 430 1336#define GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_BLOCK 431
1337 1337
1338/** 1338/**
1339 * Client to service: lookup name 1339 * Service to client: result of block lookup
1340 */ 1340 */
1341#define GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME 431 1341#define GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_BLOCK_RESPONSE 432
1342 1342
1343/** 1343/**
1344 * Service to client: result of name lookup 1344 * Client to service: store records (as authority)
1345 */ 1345 */
1346#define GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPONSE 432 1346#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE 433
1347 1347
1348/** 1348/**
1349 * Client to service: put records (for caching) 1349 * Service to client: result of store operation.
1350 */ 1350 */
1351#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT 433 1351#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE 434
1352 1352
1353/** 1353/**
1354 * Service to client: result of put operation. 1354 * Client to service: cache a block
1355 */ 1355 */
1356#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT_RESPONSE 434 1356#define GNUNET_MESSAGE_TYPE_NAMESTORE_BLOCK_CACHE 435
1357 1357
1358/** 1358/**
1359 * Client to service: create record as authority 1359 * Service to client: result of block cache request
1360 */ 1360 */
1361#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE 435 1361#define GNUNET_MESSAGE_TYPE_NAMESTORE_BLOCK_CACHE_RESPONSE 436
1362
1363/**
1364 * Service to client: result of record creation request
1365 */
1366#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE_RESPONSE 436
1367 1362
1368/** 1363/**
1369 * Client to service: "reverse" lookup for zone name based on zone key 1364 * Client to service: "reverse" lookup for zone name based on zone key
@@ -1387,6 +1382,11 @@ extern "C"
1387#define GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_SYNC 442 1382#define GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_SYNC 442
1388 1383
1389/** 1384/**
1385 * Service to client: here is a (plaintext) record you requested.
1386 */
1387#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT 443
1388
1389/**
1390 * Client to service: please start iteration; receives 1390 * Client to service: please start iteration; receives
1391 * "GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPONSE" messages in return. 1391 * "GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPONSE" messages in return.
1392 */ 1392 */
diff --git a/src/namestore/Makefile.am b/src/namestore/Makefile.am
index 82c3e32ac..5a9675517 100644
--- a/src/namestore/Makefile.am
+++ b/src/namestore/Makefile.am
@@ -25,12 +25,17 @@ if HAVE_TESTING
25SQLITE_TESTS = test_plugin_namestore_sqlite 25SQLITE_TESTS = test_plugin_namestore_sqlite
26endif 26endif
27endif 27endif
28
28if HAVE_POSTGRES 29if HAVE_POSTGRES
30# postgres doesn't even build yet; thus: experimental!
31if HAVE_EXPERIMENTAL
29POSTGRES_PLUGIN = libgnunet_plugin_namestore_postgres.la 32POSTGRES_PLUGIN = libgnunet_plugin_namestore_postgres.la
30if HAVE_TESTING 33if HAVE_TESTING
31POSTGRES_TESTS = test_plugin_namestore_postgres 34POSTGRES_TESTS = test_plugin_namestore_postgres
32endif 35endif
33endif 36endif
37endif
38
34if HAVE_TESTING 39if HAVE_TESTING
35TESTING_TESTS = \ 40TESTING_TESTS = \
36 test_namestore_api \ 41 test_namestore_api \
diff --git a/src/namestore/gnunet-namestore.c b/src/namestore/gnunet-namestore.c
index d0f68b78e..4f6eeb435 100644
--- a/src/namestore/gnunet-namestore.c
+++ b/src/namestore/gnunet-namestore.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 (C) 2012 Christian Grothoff (and other contributing authors) 3 (C) 2012, 2013 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -39,17 +39,12 @@
39static struct GNUNET_NAMESTORE_Handle *ns; 39static struct GNUNET_NAMESTORE_Handle *ns;
40 40
41/** 41/**
42 * Hash of the public key of our zone.
43 */
44static struct GNUNET_CRYPTO_ShortHashCode zone;
45
46/**
47 * Private key for the our zone. 42 * Private key for the our zone.
48 */ 43 */
49static struct GNUNET_CRYPTO_EccPrivateKey *zone_pkey; 44static struct GNUNET_CRYPTO_EccPrivateKey *zone_pkey;
50 45
51/** 46/**
52 * Keyfile to manipulate. 47 * Keyfile to manipulate. FIXME: change to ego's name!
53 */ 48 */
54static char *keyfile; 49static char *keyfile;
55 50
@@ -59,9 +54,9 @@ static char *keyfile;
59static int add; 54static int add;
60 55
61/** 56/**
62 * Queue entry for the 'add' operation. 57 * Iterator for the 'add' operation.
63 */ 58 */
64static struct GNUNET_NAMESTORE_QueueEntry *add_qe; 59static struct GNUNET_NAMESTORE_ZoneIterator *add_zit;
65 60
66/** 61/**
67 * Queue entry for the 'add-uri' operation. 62 * Queue entry for the 'add-uri' operation.
@@ -69,6 +64,11 @@ static struct GNUNET_NAMESTORE_QueueEntry *add_qe;
69static struct GNUNET_NAMESTORE_QueueEntry *add_qe_uri; 64static struct GNUNET_NAMESTORE_QueueEntry *add_qe_uri;
70 65
71/** 66/**
67 * Queue entry for the 'add' operation.
68 */
69static struct GNUNET_NAMESTORE_QueueEntry *add_qe;
70
71/**
72 * Desired action is to list records. 72 * Desired action is to list records.
73 */ 73 */
74static int list; 74static int list;
@@ -168,6 +168,7 @@ static struct GNUNET_NAMESTORE_ZoneMonitor *zm;
168 */ 168 */
169static int monitor; 169static int monitor;
170 170
171
171/** 172/**
172 * Task run on shutdown. Cleans up everything. 173 * Task run on shutdown. Cleans up everything.
173 * 174 *
@@ -291,33 +292,21 @@ del_continuation (void *cls,
291 * Process a record that was stored in the namestore. 292 * Process a record that was stored in the namestore.
292 * 293 *
293 * @param cls closure 294 * @param cls closure
294 * @param zone_key public key of the zone 295 * @param zone_key private key of the zone
295 * @param expire when does the corresponding block in the DHT expire (until
296 * when should we never do a DHT lookup for the same name again)?;
297 * GNUNET_TIME_UNIT_ZERO_ABS if there are no records of any type in the namestore,
298 * or the expiration time of the block in the namestore (even if there are zero
299 * records matching the desired record type)
300 * @param name name that is being mapped (at most 255 characters long) 296 * @param name name that is being mapped (at most 255 characters long)
301 * @param rd_len number of entries in 'rd' array 297 * @param rd_len number of entries in 'rd' array
302 * @param rd array of records with data to store 298 * @param rd array of records with data to store
303 * @param signature signature of the record block, NULL if signature is unavailable (i.e.
304 * because the user queried for a particular record type only)
305 */ 299 */
306static void 300static void
307display_record (void *cls, 301display_record (void *cls,
308 const struct GNUNET_CRYPTO_EccPublicKey *zone_key, 302 const struct GNUNET_CRYPTO_EccPrivateKey *zone_key,
309 struct GNUNET_TIME_Absolute expire,
310 const char *name, 303 const char *name,
311 unsigned int rd_len, 304 unsigned int rd_len,
312 const struct GNUNET_NAMESTORE_RecordData *rd, 305 const struct GNUNET_NAMESTORE_RecordData *rd)
313 const struct GNUNET_CRYPTO_EccSignature *signature)
314{ 306{
315 const char *typestring; 307 const char *typestring;
316 char *s; 308 char *s;
317 unsigned int i; 309 unsigned int i;
318 const char *etime;
319 struct GNUNET_TIME_Absolute aex;
320 struct GNUNET_TIME_Relative rex;
321 310
322 if (NULL == name) 311 if (NULL == name)
323 { 312 {
@@ -343,21 +332,10 @@ display_record (void *cls,
343 (unsigned int) rd[i].record_type); 332 (unsigned int) rd[i].record_type);
344 continue; 333 continue;
345 } 334 }
346 if (0 != (rd[i].flags & GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION)) 335 FPRINTF (stdout,
347 { 336 "\t%s: %s\n",
348 rex.rel_value_us = rd[i].expiration_time; 337 typestring,
349 etime = GNUNET_STRINGS_relative_time_to_string (rex, GNUNET_YES); 338 s);
350 }
351 else
352 {
353 aex.abs_value_us = rd[i].expiration_time;
354 etime = GNUNET_STRINGS_absolute_time_to_string (aex);
355 }
356 FPRINTF (stdout, "\t%s: %s (%s %s)\n", typestring, s,
357 (0 != (rd[i].flags & GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION))
358 ? _(/* what follows is relative expiration */ "for at least")
359 : _(/* what follows is absolute expiration */ "until"),
360 etime);
361 GNUNET_free (s); 339 GNUNET_free (s);
362 } 340 }
363 FPRINTF (stdout, "%s", "\n"); 341 FPRINTF (stdout, "%s", "\n");
@@ -382,31 +360,27 @@ sync_cb (void *cls)
382 * so that we can merge the information. 360 * so that we can merge the information.
383 * 361 *
384 * @param cls closure, unused 362 * @param cls closure, unused
385 * @param zone_key public key of the zone 363 * @param zone_key private key of the zone
386 * @param freshness when does the corresponding block in the DHT expire (until
387 * when should we never do a DHT lookup for the same name again)?;
388 * GNUNET_TIME_UNIT_ZERO_ABS if there are no records of any type in the namestore,
389 * or the expiration time of the block in the namestore (even if there are zero
390 * records matching the desired record type)
391 * @param rec_name name that is being mapped (at most 255 characters long) 364 * @param rec_name name that is being mapped (at most 255 characters long)
392 * @param rd_count number of entries in 'rd' array 365 * @param rd_count number of entries in 'rd' array
393 * @param rd array of records with data to store 366 * @param rd array of records with data to store
394 * @param signature signature of the record block, NULL if signature is unavailable (i.e.
395 * because the user queried for a particular record type only)
396 */ 367 */
397static void 368static void
398get_existing_record (void *cls, 369get_existing_record (void *cls,
399 const struct GNUNET_CRYPTO_EccPublicKey *zone_key, 370 const struct GNUNET_CRYPTO_EccPrivateKey *zone_key,
400 struct GNUNET_TIME_Absolute freshness,
401 const char *rec_name, 371 const char *rec_name,
402 unsigned int rd_count, 372 unsigned int rd_count,
403 const struct GNUNET_NAMESTORE_RecordData *rd, 373 const struct GNUNET_NAMESTORE_RecordData *rd)
404 const struct GNUNET_CRYPTO_EccSignature *signature)
405{ 374{
406 struct GNUNET_NAMESTORE_RecordData rdn[rd_count + 1]; 375 struct GNUNET_NAMESTORE_RecordData rdn[rd_count + 1];
407 struct GNUNET_NAMESTORE_RecordData *rde; 376 struct GNUNET_NAMESTORE_RecordData *rde;
408 377
409 add_qe = NULL; 378 if ( (NULL != zone_key) &&
379 (0 != strcmp (rec_name, name)) )
380 {
381 GNUNET_NAMESTORE_zone_iterator_next (add_zit);
382 return;
383 }
410 memset (rdn, 0, sizeof (struct GNUNET_NAMESTORE_RecordData)); 384 memset (rdn, 0, sizeof (struct GNUNET_NAMESTORE_RecordData));
411 memcpy (&rdn[1], rd, rd_count * sizeof (struct GNUNET_NAMESTORE_RecordData)); 385 memcpy (&rdn[1], rd, rd_count * sizeof (struct GNUNET_NAMESTORE_RecordData));
412 /* FIXME: should add some logic to overwrite records if there 386 /* FIXME: should add some logic to overwrite records if there
@@ -416,27 +390,20 @@ get_existing_record (void *cls,
416 rde->data = data; 390 rde->data = data;
417 rde->data_size = data_size; 391 rde->data_size = data_size;
418 rde->record_type = type; 392 rde->record_type = type;
419 if (GNUNET_YES == etime_is_rel)
420 {
421 rde->expiration_time = etime_rel.rel_value_us;
422 rde->flags |= GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION;
423 }
424 else if (GNUNET_NO == etime_is_rel)
425 {
426 rde->expiration_time = etime_abs.abs_value_us;
427 }
428 if (1 != nonauthority) 393 if (1 != nonauthority)
429 rde->flags |= GNUNET_NAMESTORE_RF_AUTHORITY; 394 rde->flags |= GNUNET_NAMESTORE_RF_AUTHORITY;
430 if (1 != public) 395 if (1 != public)
431 rde->flags |= GNUNET_NAMESTORE_RF_PRIVATE; 396 rde->flags |= GNUNET_NAMESTORE_RF_PRIVATE;
432 GNUNET_assert (NULL != name); 397 GNUNET_assert (NULL != name);
433 add_qe = GNUNET_NAMESTORE_record_put_by_authority (ns, 398 add_qe = GNUNET_NAMESTORE_records_store (ns,
434 zone_pkey, 399 zone_pkey,
435 name, 400 name,
436 rd_count + 1, 401 rd_count + 1,
437 rde, 402 rde,
438 &add_continuation, 403 &add_continuation,
439 &add_qe); 404 &add_qe);
405 GNUNET_NAMESTORE_zone_iteration_stop (add_zit);
406 add_zit = NULL;
440} 407}
441 408
442 409
@@ -494,7 +461,6 @@ testservice_task (void *cls,
494 } 461 }
495 GNUNET_CRYPTO_ecc_key_get_public (zone_pkey, 462 GNUNET_CRYPTO_ecc_key_get_public (zone_pkey,
496 &pub); 463 &pub);
497 GNUNET_CRYPTO_short_hash (&pub, sizeof (pub), &zone);
498 464
499 ns = GNUNET_NAMESTORE_connect (cfg); 465 ns = GNUNET_NAMESTORE_connect (cfg);
500 if (NULL == ns) 466 if (NULL == ns)
@@ -590,12 +556,10 @@ testservice_task (void *cls,
590 ret = 1; 556 ret = 1;
591 return; 557 return;
592 } 558 }
593 add_qe = GNUNET_NAMESTORE_lookup_record (ns, 559 add_zit = GNUNET_NAMESTORE_zone_iteration_start (ns,
594 &zone, 560 zone_pkey,
595 name, 561 &get_existing_record,
596 0, 562 NULL);
597 &get_existing_record,
598 NULL);
599 } 563 }
600 if (del) 564 if (del)
601 { 565 {
@@ -608,12 +572,12 @@ testservice_task (void *cls,
608 ret = 1; 572 ret = 1;
609 return; 573 return;
610 } 574 }
611 del_qe = GNUNET_NAMESTORE_record_put_by_authority (ns, 575 del_qe = GNUNET_NAMESTORE_records_store (ns,
612 zone_pkey, 576 zone_pkey,
613 name, 577 name,
614 0, NULL, 578 0, NULL,
615 &del_continuation, 579 &del_continuation,
616 NULL); 580 NULL);
617 } 581 }
618 if (list) 582 if (list)
619 { 583 {
@@ -626,24 +590,22 @@ testservice_task (void *cls,
626 must_not_flags |= GNUNET_NAMESTORE_RF_PRIVATE; 590 must_not_flags |= GNUNET_NAMESTORE_RF_PRIVATE;
627 591
628 list_it = GNUNET_NAMESTORE_zone_iteration_start (ns, 592 list_it = GNUNET_NAMESTORE_zone_iteration_start (ns,
629 &zone, 593 zone_pkey,
630 GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION,
631 must_not_flags,
632 &display_record, 594 &display_record,
633 NULL); 595 NULL);
634 } 596 }
635 if (NULL != uri) 597 if (NULL != uri)
636 { 598 {
637 char sh[53]; 599 char sh[105];
638 char sname[64]; 600 char sname[64];
639 struct GNUNET_CRYPTO_ShortHashCode sc; 601 struct GNUNET_CRYPTO_EccPublicKey pkey;
640 602
641 if ( (2 != (sscanf (uri, 603 if ( (2 != (sscanf (uri,
642 "gnunet://gns/%52s/%63s", 604 "gnunet://gns/%104s/%63s",
643 sh, 605 sh,
644 sname)) ) || 606 sname)) ) ||
645 (GNUNET_OK != 607 (GNUNET_OK !=
646 GNUNET_CRYPTO_short_hash_from_string (sh, &sc)) ) 608 GNUNET_CRYPTO_ecc_public_key_from_string (sh, strlen (sh), &pkey)) )
647 { 609 {
648 fprintf (stderr, 610 fprintf (stderr,
649 _("Invalid URI `%s'\n"), 611 _("Invalid URI `%s'\n"),
@@ -653,8 +615,8 @@ testservice_task (void *cls,
653 return; 615 return;
654 } 616 }
655 memset (&rd, 0, sizeof (rd)); 617 memset (&rd, 0, sizeof (rd));
656 rd.data = &sc; 618 rd.data = &pkey;
657 rd.data_size = sizeof (struct GNUNET_CRYPTO_ShortHashCode); 619 rd.data_size = sizeof (struct GNUNET_CRYPTO_EccPublicKey);
658 rd.record_type = GNUNET_NAMESTORE_TYPE_PKEY; 620 rd.record_type = GNUNET_NAMESTORE_TYPE_PKEY;
659 if (GNUNET_YES == etime_is_rel) 621 if (GNUNET_YES == etime_is_rel)
660 { 622 {
@@ -667,18 +629,18 @@ testservice_task (void *cls,
667 rd.expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us; 629 rd.expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
668 if (1 != nonauthority) 630 if (1 != nonauthority)
669 rd.flags |= GNUNET_NAMESTORE_RF_AUTHORITY; 631 rd.flags |= GNUNET_NAMESTORE_RF_AUTHORITY;
670 add_qe_uri = GNUNET_NAMESTORE_record_put_by_authority (ns, 632 add_qe_uri = GNUNET_NAMESTORE_records_store (ns,
671 zone_pkey, 633 zone_pkey,
672 sname, 634 sname,
673 1, 635 1,
674 &rd, 636 &rd,
675 &add_continuation, 637 &add_continuation,
676 &add_qe_uri); 638 &add_qe_uri);
677 } 639 }
678 if (monitor) 640 if (monitor)
679 { 641 {
680 zm = GNUNET_NAMESTORE_zone_monitor_start (cfg, 642 zm = GNUNET_NAMESTORE_zone_monitor_start (cfg,
681 &zone, 643 zone_pkey,
682 &display_record, 644 &display_record,
683 &sync_cb, 645 &sync_cb,
684 NULL); 646 NULL);
diff --git a/src/namestore/namestore.h b/src/namestore/namestore.h
index 58ecbf65d..ca712e136 100644
--- a/src/namestore/namestore.h
+++ b/src/namestore/namestore.h
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 (C) 2009 Christian Grothoff (and other contributing authors) 3 (C) 2011-2013 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -22,6 +22,7 @@
22 * @file namestore/namestore.h 22 * @file namestore/namestore.h
23 * @brief common internal definitions for namestore service 23 * @brief common internal definitions for namestore service
24 * @author Matthias Wachs 24 * @author Matthias Wachs
25 * @author Christian Grothoff
25 */ 26 */
26#ifndef NAMESTORE_H 27#ifndef NAMESTORE_H
27#define NAMESTORE_H 28#define NAMESTORE_H
@@ -33,51 +34,6 @@
33 34
34GNUNET_NETWORK_STRUCT_BEGIN 35GNUNET_NETWORK_STRUCT_BEGIN
35 36
36
37/**
38 * A GNS record serialized for network transmission.
39 *
40 * Layout is [struct GNUNET_NAMESTORE_NetworkRecord][char[data_size] data]
41 */
42struct GNUNET_NAMESTORE_NetworkRecord
43{
44 /**
45 * Expiration time for the DNS record.
46 */
47 struct GNUNET_TIME_AbsoluteNBO expiration;
48
49 /**
50 * Number of bytes in 'data'.
51 */
52 uint32_t data_size;
53
54 /**
55 * Type of the GNS/DNS record.
56 */
57 uint32_t record_type;
58
59 /**
60 * Flags for the record.
61 */
62 uint32_t flags;
63};
64
65
66
67/**
68 * Connect to namestore service. FIXME: UNNECESSARY.
69 */
70struct StartMessage
71{
72
73 /**
74 * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_START
75 */
76 struct GNUNET_MessageHeader header;
77
78};
79
80
81/** 37/**
82 * Generic namestore message with op id 38 * Generic namestore message with op id
83 */ 39 */
@@ -97,38 +53,30 @@ struct GNUNET_NAMESTORE_Header
97 53
98 54
99/** 55/**
100 * Lookup a name in the namestore 56 * Lookup a block in the namestore
101 */ 57 */
102struct LookupNameMessage 58struct LookupBlockMessage
103{ 59{
104 struct GNUNET_NAMESTORE_Header gns_header;
105
106 /**
107 * The zone
108 */
109 struct GNUNET_CRYPTO_ShortHashCode zone;
110
111 /** 60 /**
112 * Requested record type 61 * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_BLOCK
113 */ 62 */
114 uint32_t record_type; 63 struct GNUNET_NAMESTORE_Header gns_header;
115 64
116 /** 65 /**
117 * Length of the name 66 * The query.
118 */ 67 */
119 uint32_t name_len; 68 struct GNUNET_HashCode query;
120 69
121 /* 0-terminated name here */
122}; 70};
123 71
124 72
125/** 73/**
126 * Lookup response 74 * Lookup response
127 */ 75 */
128struct LookupNameResponseMessage 76struct LookupBlockResponseMessage
129{ 77{
130 /** 78 /**
131 * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPONSE 79 * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_BLOCK_RESPONSE
132 */ 80 */
133 struct GNUNET_NAMESTORE_Header gns_header; 81 struct GNUNET_NAMESTORE_Header gns_header;
134 82
@@ -138,48 +86,26 @@ struct LookupNameResponseMessage
138 struct GNUNET_TIME_AbsoluteNBO expire; 86 struct GNUNET_TIME_AbsoluteNBO expire;
139 87
140 /** 88 /**
141 * Name length 89 * Signature.
142 */
143 uint16_t name_len;
144
145 /**
146 * Bytes of serialized record data
147 */
148 uint16_t rd_len;
149
150 /**
151 * Number of records contained
152 */
153 uint16_t rd_count;
154
155 /**
156 * Is the signature valid
157 * GNUNET_YES or GNUNET_NO
158 */
159 int16_t contains_sig;
160
161 /**
162 * All zeros if 'contains_sig' is GNUNET_NO.
163 */ 90 */
164 struct GNUNET_CRYPTO_EccSignature signature; 91 struct GNUNET_CRYPTO_EccSignature signature;
165 92
166 /** 93 /**
167 * The public key for the name 94 * Derived public key.
168 */ 95 */
169 struct GNUNET_CRYPTO_EccPublicKey public_key; 96 struct GNUNET_CRYPTO_EccPublicKey derived_key;
170 97
171 /* 0-terminated name and serialized record data */ 98 /* follwed by encrypted block data */
172 /* rd_len bytes serialized record data */
173}; 99};
174 100
175 101
176/** 102/**
177 * Put a record to the namestore 103 * Cache a record in the namestore.
178 */ 104 */
179struct RecordPutMessage 105struct BlockCacheMessage
180{ 106{
181 /** 107 /**
182 * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_RECORD_PUT 108 * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_BLOCK_CACHE
183 */ 109 */
184 struct GNUNET_NAMESTORE_Header gns_header; 110 struct GNUNET_NAMESTORE_Header gns_header;
185 111
@@ -189,70 +115,49 @@ struct RecordPutMessage
189 struct GNUNET_TIME_AbsoluteNBO expire; 115 struct GNUNET_TIME_AbsoluteNBO expire;
190 116
191 /** 117 /**
192 * Name length 118 * Signature.
193 */
194 uint16_t name_len;
195
196 /**
197 * Length of serialized record data
198 */
199 uint16_t rd_len;
200
201 /**
202 * Number of records contained
203 */
204 uint16_t rd_count;
205
206 /**
207 * always zero (for alignment)
208 */
209 uint16_t reserved;
210
211 /**
212 * The signature
213 */ 119 */
214 struct GNUNET_CRYPTO_EccSignature signature; 120 struct GNUNET_CRYPTO_EccSignature signature;
215 121
216 /** 122 /**
217 * The public key 123 * Derived public key.
218 */ 124 */
219 struct GNUNET_CRYPTO_EccPublicKey public_key; 125 struct GNUNET_CRYPTO_EccPublicKey derived_key;
220
221 /* name (0-terminated) followed by "rd_count" serialized records */
222 126
127 /* follwed by encrypted block data */
223}; 128};
224 129
225 130
226/** 131/**
227 * Put a record to the namestore response 132 * Response to a request to cache a block.
228 */ 133 */
229struct RecordPutResponseMessage 134struct BlockCacheResponseMessage
230{ 135{
231 /** 136 /**
232 * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT_RESPONSE 137 * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_BLOCK_CACHE_RESPONSE
233 */ 138 */
234 struct GNUNET_NAMESTORE_Header gns_header; 139 struct GNUNET_NAMESTORE_Header gns_header;
235 140
236 /** 141 /**
237 * result: 142 * name length: GNUNET_NO already exists, GNUNET_YES on success, GNUNET_SYSERR error
238 * GNUNET_SYSERR on failure
239 * GNUNET_OK on success
240 */ 143 */
241 int32_t op_result; 144 int32_t op_result;
242}; 145};
243 146
244 147
245/** 148/**
246 * Create a record and put it to the namestore 149 * Store a record to the namestore (as authority).
247 * Memory layout:
248 */ 150 */
249struct RecordCreateMessage 151struct RecordStoreMessage
250{ 152{
251 /** 153 /**
252 * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE 154 * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_RECORD_STORE
253 */ 155 */
254 struct GNUNET_NAMESTORE_Header gns_header; 156 struct GNUNET_NAMESTORE_Header gns_header;
255 157
158 /**
159 * Expiration time
160 */
256 struct GNUNET_TIME_AbsoluteNBO expire; 161 struct GNUNET_TIME_AbsoluteNBO expire;
257 162
258 /** 163 /**
@@ -266,41 +171,47 @@ struct RecordCreateMessage
266 uint16_t rd_len; 171 uint16_t rd_len;
267 172
268 /** 173 /**
269 * Record count 174 * Number of records contained
270 */ 175 */
271 uint16_t rd_count; 176 uint16_t rd_count;
272 177
273 /** 178 /**
274 * always zero 179 * always zero (for alignment)
275 */ 180 */
276 uint16_t reserved; 181 uint16_t reserved;
277 182
183 /**
184 * The private key of the authority.
185 */
278 struct GNUNET_CRYPTO_EccPrivateKey private_key; 186 struct GNUNET_CRYPTO_EccPrivateKey private_key;
279 187
280 /* followed by: 188 /* followed by:
281 * name with length name_len 189 * name with length name_len
282 * serialized record data with length rd_len 190 * serialized record data with rd_count records
283 */ 191 */
284}; 192};
285 193
286 194
287/** 195/**
288 * Create a record to the namestore response 196 * Response to a record storage request.
289 */ 197 */
290struct RecordCreateResponseMessage 198struct RecordStoreResponseMessage
291{ 199{
292 /** 200 /**
293 * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE_RESPONSE 201 * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE
294 */ 202 */
295 struct GNUNET_NAMESTORE_Header gns_header; 203 struct GNUNET_NAMESTORE_Header gns_header;
296 204
297 /** 205 /**
298 * name length: GNUNET_NO already exists, GNUNET_YES on success, GNUNET_SYSERR error 206 * result:
207 * GNUNET_SYSERR on failure
208 * GNUNET_OK on success
299 */ 209 */
300 int32_t op_result; 210 int32_t op_result;
301}; 211};
302 212
303 213
214
304/** 215/**
305 * Lookup a name for a zone hash 216 * Lookup a name for a zone hash
306 */ 217 */
@@ -312,14 +223,14 @@ struct ZoneToNameMessage
312 struct GNUNET_NAMESTORE_Header gns_header; 223 struct GNUNET_NAMESTORE_Header gns_header;
313 224
314 /** 225 /**
315 * The hash of public key of the zone to look up in 226 * The private key of the zone to look up in
316 */ 227 */
317 struct GNUNET_CRYPTO_ShortHashCode zone; 228 struct GNUNET_CRYPTO_EccPrivateKey zone;
318 229
319 /** 230 /**
320 * The hash of the public key of the target zone 231 * The public key of the target zone
321 */ 232 */
322 struct GNUNET_CRYPTO_ShortHashCode value_zone; 233 struct GNUNET_CRYPTO_EccPublicKey value_zone;
323}; 234};
324 235
325 236
@@ -334,11 +245,6 @@ struct ZoneToNameResponseMessage
334 struct GNUNET_NAMESTORE_Header gns_header; 245 struct GNUNET_NAMESTORE_Header gns_header;
335 246
336 /** 247 /**
337 * Record block expiration
338 */
339 struct GNUNET_TIME_AbsoluteNBO expire;
340
341 /**
342 * Length of the name 248 * Length of the name
343 */ 249 */
344 uint16_t name_len; 250 uint16_t name_len;
@@ -360,66 +266,93 @@ struct ZoneToNameResponseMessage
360 int16_t res; 266 int16_t res;
361 267
362 /** 268 /**
363 * Signature 269 * The private key of the zone that contained the name.
364 */ 270 */
365 struct GNUNET_CRYPTO_EccSignature signature; 271 struct GNUNET_CRYPTO_EccPrivateKey zone;
366 272
367 /** 273 /* followed by:
368 * Publik key 274 * name with length name_len
275 * serialized record data with rd_count records
369 */ 276 */
370 struct GNUNET_CRYPTO_EccPublicKey zone_key;
371 277
372}; 278};
373 279
374 280
375/** 281/**
376 * Start monitoring a zone. 282 * Record is returned from the namestore (as authority).
377 */ 283 */
378struct ZoneMonitorStartMessage 284struct RecordResultMessage
379{ 285{
380 /** 286 /**
381 * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_START 287 * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT
382 */ 288 */
383 struct GNUNET_NAMESTORE_Header gns_header; 289 struct GNUNET_NAMESTORE_Header gns_header;
384 290
385 /** 291 /**
386 * Zone hash 292 * Name length
293 */
294 uint16_t name_len;
295
296 /**
297 * Length of serialized record data
298 */
299 uint16_t rd_len;
300
301 /**
302 * Number of records contained
303 */
304 uint16_t rd_count;
305
306 /**
307 * always zero (for alignment)
387 */ 308 */
388 struct GNUNET_CRYPTO_ShortHashCode zone; 309 uint16_t reserved;
389 310
390 /** 311 /**
391 * All zones. GNUNET_YES to monitor all zones, 312 * The private key of the authority.
392 * GNUNET_NO to only monitor 'zone'. In NBO.
393 */ 313 */
394 uint32_t all_zones GNUNET_PACKED; 314 struct GNUNET_CRYPTO_EccPrivateKey private_key;
395 315
316 /* followed by:
317 * name with length name_len
318 * serialized record data with rd_count records
319 */
396}; 320};
397 321
398 322
399/** 323/**
400 * Start a zone iteration for the given zone 324 * Start monitoring a zone.
401 */ 325 */
402struct ZoneIterationStartMessage 326struct ZoneMonitorStartMessage
403{ 327{
404 /** 328 /**
405 * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START 329 * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_START
406 */ 330 */
407 struct GNUNET_NAMESTORE_Header gns_header; 331 struct GNUNET_NAMESTORE_Header gns_header;
408 332
409 /** 333 /**
410 * Zone hash 334 * Zone key.
411 */ 335 */
412 struct GNUNET_CRYPTO_ShortHashCode zone; 336 struct GNUNET_CRYPTO_EccPrivateKey zone;
337
338};
339
413 340
341/**
342 * Start a zone iteration for the given zone
343 */
344struct ZoneIterationStartMessage
345{
414 /** 346 /**
415 * Which flags must be included 347 * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START
416 */ 348 */
417 uint16_t must_have_flags; 349 struct GNUNET_NAMESTORE_Header gns_header;
418 350
419 /** 351 /**
420 * Which flags must not be included 352 * Zone key.
421 */ 353 */
422 uint16_t must_not_have_flags; 354 struct GNUNET_CRYPTO_EccPrivateKey zone;
355
423}; 356};
424 357
425 358
diff --git a/src/namestore/namestore_api.c b/src/namestore/namestore_api.c
index c5b213954..acc9b4e37 100644
--- a/src/namestore/namestore_api.c
+++ b/src/namestore/namestore_api.c
@@ -75,7 +75,7 @@ struct GNUNET_NAMESTORE_QueueEntry
75 /** 75 /**
76 * Function to call with the records we get back; or NULL. 76 * Function to call with the records we get back; or NULL.
77 */ 77 */
78 GNUNET_NAMESTORE_RecordProcessor proc; 78 GNUNET_NAMESTORE_RecordMonitor proc;
79 79
80 /** 80 /**
81 * Closure for 'proc'. 81 * Closure for 'proc'.
@@ -83,6 +83,16 @@ struct GNUNET_NAMESTORE_QueueEntry
83 void *proc_cls; 83 void *proc_cls;
84 84
85 /** 85 /**
86 * Function to call with the blocks we get back; or NULL.
87 */
88 GNUNET_NAMESTORE_BlockProcessor block_proc;
89
90 /**
91 * Closure for 'block_proc'.
92 */
93 void *block_proc_cls;
94
95 /**
86 * The operation id this zone iteration operation has 96 * The operation id this zone iteration operation has
87 */ 97 */
88 uint32_t op_id; 98 uint32_t op_id;
@@ -114,7 +124,7 @@ struct GNUNET_NAMESTORE_ZoneIterator
114 /** 124 /**
115 * The continuation to call with the results 125 * The continuation to call with the results
116 */ 126 */
117 GNUNET_NAMESTORE_RecordProcessor proc; 127 GNUNET_NAMESTORE_RecordMonitor proc;
118 128
119 /** 129 /**
120 * Closure for 'proc'. 130 * Closure for 'proc'.
@@ -122,23 +132,15 @@ struct GNUNET_NAMESTORE_ZoneIterator
122 void* proc_cls; 132 void* proc_cls;
123 133
124 /** 134 /**
125 * If this iterator iterates over a specific zone this value contains the 135 * Private key of the zone.
126 * short hash of the zone
127 */ 136 */
128 struct GNUNET_CRYPTO_ShortHashCode zone; 137 struct GNUNET_CRYPTO_EccPrivateKey zone;
129 138
130 /** 139 /**
131 * The operation id this zone iteration operation has 140 * The operation id this zone iteration operation has
132 */ 141 */
133 uint32_t op_id; 142 uint32_t op_id;
134 143
135 /**
136 * GNUNET_YES if this iterator iterates over a specific zone
137 * GNUNET_NO if this iterator iterates over all zones
138 *
139 * Zone is stored GNUNET_CRYPTO_ShortHashCode 'zone';
140 */
141 int has_zone;
142}; 144};
143 145
144 146
@@ -164,10 +166,6 @@ struct PendingMessage
164 */ 166 */
165 size_t size; 167 size_t size;
166 168
167 /**
168 * Is this the 'START' message?
169 */
170 int is_init;
171}; 169};
172 170
173 171
@@ -233,6 +231,11 @@ struct GNUNET_NAMESTORE_Handle
233 int reconnect; 231 int reconnect;
234 232
235 /** 233 /**
234 * Did we start to receive yet?
235 */
236 int is_receiving;
237
238 /**
236 * The last operation id used for a NAMESTORE operation 239 * The last operation id used for a NAMESTORE operation
237 */ 240 */
238 uint32_t last_op_id_used; 241 uint32_t last_op_id_used;
@@ -250,7 +253,7 @@ force_reconnect (struct GNUNET_NAMESTORE_Handle *h);
250 253
251 254
252/** 255/**
253 * Handle an incoming message of type 'GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPONSE' 256 * Handle an incoming message of type 'GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_BLOCK_RESPONSE'
254 * 257 *
255 * @param qe the respective entry in the message queue 258 * @param qe the respective entry in the message queue
256 * @param msg the message we received 259 * @param msg the message we received
@@ -258,73 +261,41 @@ force_reconnect (struct GNUNET_NAMESTORE_Handle *h);
258 * @return GNUNET_OK on success, GNUNET_SYSERR on error and we did NOT notify the client 261 * @return GNUNET_OK on success, GNUNET_SYSERR on error and we did NOT notify the client
259 */ 262 */
260static int 263static int
261handle_lookup_name_response (struct GNUNET_NAMESTORE_QueueEntry *qe, 264handle_lookup_block_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
262 const struct LookupNameResponseMessage * msg, 265 const struct LookupBlockResponseMessage *msg,
263 size_t size) 266 size_t size)
264{ 267{
265 const char *name; 268 struct GNUNET_NAMESTORE_Block *block;
266 const char * rd_tmp; 269 char buf[size + sizeof (struct GNUNET_NAMESTORE_Block) - sizeof (struct LookupBlockResponseMessage)];
267 const struct GNUNET_CRYPTO_EccSignature *signature;
268 struct GNUNET_TIME_Absolute expire;
269 const struct GNUNET_CRYPTO_EccPublicKey *public_key_tmp;
270 size_t exp_msg_len;
271 size_t msg_len;
272 size_t name_len;
273 size_t rd_len;
274 int contains_sig;
275 int rd_count;
276 270
277 LOG (GNUNET_ERROR_TYPE_DEBUG, 271 LOG (GNUNET_ERROR_TYPE_DEBUG,
278 "Received `%s'\n", 272 "Received `%s'\n",
279 "LOOKUP_NAME_RESPONSE"); 273 "LOOKUP_BLOCK_RESPONSE");
280 rd_len = ntohs (msg->rd_len); 274 block = (struct GNUNET_NAMESTORE_Block *) buf;
281 rd_count = ntohs (msg->rd_count); 275 block->signature = msg->signature;
282 msg_len = ntohs (msg->gns_header.header.size); 276 block->derived_key = msg->derived_key;
283 name_len = ntohs (msg->name_len); 277 block->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
284 contains_sig = ntohs (msg->contains_sig); 278 block->purpose.size = htonl (size - sizeof (struct LookupBlockResponseMessage) + sizeof (struct GNUNET_TIME_AbsoluteNBO));
285 expire = GNUNET_TIME_absolute_ntoh (msg->expire); 279 block->expiration_time = msg->expire;
286 exp_msg_len = sizeof (struct LookupNameResponseMessage) + 280 memcpy (&block[1],
287 name_len + rd_len; 281 &msg[1],
288 if (msg_len != exp_msg_len) 282 size - sizeof (struct LookupBlockResponseMessage));
283 if (GNUNET_OK !=
284 GNUNET_NAMESTORE_block_verify (block))
289 { 285 {
290 GNUNET_break (0); 286 GNUNET_break (0);
291 return GNUNET_SYSERR; 287 return GNUNET_SYSERR;
292 } 288 }
293 name = (const char *) &msg[1]; 289 if (NULL != qe->block_proc)
294 if ( (name_len > 0) && 290 qe->block_proc (qe->proc_cls, block);
295 ('\0' != name[name_len -1]) ) 291 else
296 {
297 GNUNET_break (0); 292 GNUNET_break (0);
298 return GNUNET_SYSERR;
299 }
300 rd_tmp = &name[name_len];
301 {
302 struct GNUNET_NAMESTORE_RecordData rd[rd_count];
303
304 if (GNUNET_OK != GNUNET_NAMESTORE_records_deserialize(rd_len, rd_tmp, rd_count, rd))
305 {
306 GNUNET_break (0);
307 return GNUNET_SYSERR;
308 }
309 if (GNUNET_NO == contains_sig)
310 signature = NULL;
311 else
312 signature = &msg->signature;
313 if (0 == name_len)
314 name = NULL;
315 if (NULL != name)
316 public_key_tmp = &msg->public_key;
317 else
318 public_key_tmp = NULL;
319 if (NULL != qe->proc)
320 qe->proc (qe->proc_cls, public_key_tmp, expire, name, rd_count, (rd_count > 0) ? rd : NULL, signature);
321 }
322 return GNUNET_OK; 293 return GNUNET_OK;
323} 294}
324 295
325 296
326/** 297/**
327 * Handle an incoming message of type 'GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT_RESPONSE' 298 * Handle an incoming message of type 'GNUNET_MESSAGE_TYPE_NAMESTORE_BLOCK_CACHE_RESPONSE'
328 * 299 *
329 * @param qe the respective entry in the message queue 300 * @param qe the respective entry in the message queue
330 * @param msg the message we received 301 * @param msg the message we received
@@ -332,24 +303,24 @@ handle_lookup_name_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
332 * @return GNUNET_OK on success, GNUNET_SYSERR on error and we did NOT notify the client 303 * @return GNUNET_OK on success, GNUNET_SYSERR on error and we did NOT notify the client
333 */ 304 */
334static int 305static int
335handle_record_put_response (struct GNUNET_NAMESTORE_QueueEntry *qe, 306handle_block_cache_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
336 const struct RecordPutResponseMessage* msg, 307 const struct BlockCacheResponseMessage *msg,
337 size_t size) 308 size_t size)
338{ 309{
339 int res; 310 int res;
340 311
341 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received `%s'\n", 312 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received `%s'\n",
342 "RECORD_PUT_RESPONSE"); 313 "BLOCK_CACHE_RESPONSE");
343 res = ntohl (msg->op_result); 314 res = ntohl (msg->op_result);
344 /* TODO: add actual error message from namestore to response... */ 315 /* TODO: add actual error message from namestore to response... */
345 if (NULL != qe->cont) 316 if (NULL != qe->cont)
346 qe->cont (qe->cont_cls, res, (GNUNET_OK == res) ? NULL : _("Namestore failed to add record")); 317 qe->cont (qe->cont_cls, res, (GNUNET_OK == res) ? NULL : _("Namestore failed to cache block"));
347 return GNUNET_OK; 318 return GNUNET_OK;
348} 319}
349 320
350 321
351/** 322/**
352 * Handle an incoming message of type 'GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE_RESPONSE' 323 * Handle an incoming message of type 'GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE'
353 * 324 *
354 * @param qe the respective entry in the message queue 325 * @param qe the respective entry in the message queue
355 * @param msg the message we received 326 * @param msg the message we received
@@ -357,19 +328,19 @@ handle_record_put_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
357 * @return GNUNET_OK on success, GNUNET_SYSERR on error and we did NOT notify the client 328 * @return GNUNET_OK on success, GNUNET_SYSERR on error and we did NOT notify the client
358 */ 329 */
359static int 330static int
360handle_record_create_response (struct GNUNET_NAMESTORE_QueueEntry *qe, 331handle_record_store_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
361 const struct RecordCreateResponseMessage* msg, 332 const struct RecordStoreResponseMessage* msg,
362 size_t size) 333 size_t size)
363{ 334{
364 int res; 335 int res;
365 const char *emsg; 336 const char *emsg;
366 337
367 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received `%s'\n", 338 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received `%s'\n",
368 "RECORD_CREATE_RESPONSE"); 339 "RECORD_STORE_RESPONSE");
369 /* TODO: add actual error message from namestore to response... */ 340 /* TODO: add actual error message from namestore to response... */
370 res = ntohl (msg->op_result); 341 res = ntohl (msg->op_result);
371 if (GNUNET_SYSERR == res) 342 if (GNUNET_SYSERR == res)
372 emsg = _("Namestore failed to add record\n"); 343 emsg = _("Namestore failed to store record\n");
373 else 344 else
374 emsg = NULL; 345 emsg = NULL;
375 if (NULL != qe->cont) 346 if (NULL != qe->cont)
@@ -379,6 +350,70 @@ handle_record_create_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
379 350
380 351
381/** 352/**
353 * Handle an incoming message of type 'GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT'
354 *
355 * @param qe the respective entry in the message queue
356 * @param msg the message we received
357 * @param size the message size
358 * @return GNUNET_OK on success, GNUNET_SYSERR on error and we did NOT notify the client
359 */
360static int
361handle_record_result (struct GNUNET_NAMESTORE_QueueEntry *qe,
362 const struct RecordResultMessage *msg,
363 size_t size)
364{
365 const char *name;
366 const char *rd_tmp;
367 size_t exp_msg_len;
368 size_t msg_len;
369 size_t name_len;
370 size_t rd_len;
371 unsigned int rd_count;
372
373 LOG (GNUNET_ERROR_TYPE_DEBUG,
374 "Received `%s'\n",
375 "RECORD_RESULT");
376 rd_len = ntohs (msg->rd_len);
377 rd_count = ntohs (msg->rd_count);
378 msg_len = ntohs (msg->gns_header.header.size);
379 name_len = ntohs (msg->name_len);
380 GNUNET_break (0 == ntohs (msg->reserved));
381 exp_msg_len = sizeof (struct RecordResultMessage) + name_len + rd_len;
382 if (msg_len != exp_msg_len)
383 {
384 GNUNET_break (0);
385 return GNUNET_SYSERR;
386 }
387 name = (const char *) &msg[1];
388 if ( (name_len > 0) &&
389 ('\0' != name[name_len -1]) )
390 {
391 GNUNET_break (0);
392 return GNUNET_SYSERR;
393 }
394 rd_tmp = &name[name_len];
395 {
396 struct GNUNET_NAMESTORE_RecordData rd[rd_count];
397
398 if (GNUNET_OK != GNUNET_NAMESTORE_records_deserialize(rd_len, rd_tmp, rd_count, rd))
399 {
400 GNUNET_break (0);
401 return GNUNET_SYSERR;
402 }
403 if (0 == name_len)
404 name = NULL;
405 if (NULL != qe->proc)
406 qe->proc (qe->proc_cls,
407 &msg->private_key,
408 name,
409 rd_count,
410 (rd_count > 0) ? rd : NULL);
411 }
412 return GNUNET_OK;
413}
414
415
416/**
382 * Handle an incoming message of type 'GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE' 417 * Handle an incoming message of type 'GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE'
383 * 418 *
384 * @param qe the respective entry in the message queue 419 * @param qe the respective entry in the message queue
@@ -389,16 +424,15 @@ handle_record_create_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
389 */ 424 */
390static int 425static int
391handle_zone_to_name_response (struct GNUNET_NAMESTORE_QueueEntry *qe, 426handle_zone_to_name_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
392 const struct ZoneToNameResponseMessage* msg, 427 const struct ZoneToNameResponseMessage *msg,
393 size_t size) 428 size_t size)
394{ 429{
395 int res; 430 int res;
396 struct GNUNET_TIME_Absolute expire;
397 size_t name_len; 431 size_t name_len;
398 size_t rd_ser_len; 432 size_t rd_ser_len;
399 unsigned int rd_count; 433 unsigned int rd_count;
400 const char * name_tmp; 434 const char *name_tmp;
401 const char * rd_tmp; 435 const char *rd_tmp;
402 436
403 LOG (GNUNET_ERROR_TYPE_DEBUG, 437 LOG (GNUNET_ERROR_TYPE_DEBUG,
404 "Received `%s'\n", 438 "Received `%s'\n",
@@ -417,7 +451,6 @@ handle_zone_to_name_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
417 name_len = ntohs (msg->name_len); 451 name_len = ntohs (msg->name_len);
418 rd_count = ntohs (msg->rd_count); 452 rd_count = ntohs (msg->rd_count);
419 rd_ser_len = ntohs (msg->rd_len); 453 rd_ser_len = ntohs (msg->rd_len);
420 expire = GNUNET_TIME_absolute_ntoh(msg->expire);
421 name_tmp = (const char *) &msg[1]; 454 name_tmp = (const char *) &msg[1];
422 if ( (name_len > 0) && 455 if ( (name_len > 0) &&
423 ('\0' != name_tmp[name_len -1]) ) 456 ('\0' != name_tmp[name_len -1]) )
@@ -435,7 +468,10 @@ handle_zone_to_name_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
435 } 468 }
436 /* normal end, call continuation with result */ 469 /* normal end, call continuation with result */
437 if (NULL != qe->proc) 470 if (NULL != qe->proc)
438 qe->proc (qe->proc_cls, &msg->zone_key, expire, name_tmp, rd_count, rd, &msg->signature); 471 qe->proc (qe->proc_cls,
472 &msg->zone,
473 name_tmp,
474 rd_count, rd);
439 /* return is important here: break would call continuation with error! */ 475 /* return is important here: break would call continuation with error! */
440 return GNUNET_OK; 476 return GNUNET_OK;
441 } 477 }
@@ -445,7 +481,7 @@ handle_zone_to_name_response (struct GNUNET_NAMESTORE_QueueEntry *qe,
445 } 481 }
446 /* error case, call continuation with error */ 482 /* error case, call continuation with error */
447 if (NULL != qe->proc) 483 if (NULL != qe->proc)
448 qe->proc (qe->proc_cls, NULL, GNUNET_TIME_UNIT_ZERO_ABS, NULL, 0, NULL, NULL); 484 qe->proc (qe->proc_cls, NULL, NULL, 0, NULL);
449 return GNUNET_OK; 485 return GNUNET_OK;
450} 486}
451 487
@@ -469,27 +505,27 @@ manage_record_operations (struct GNUNET_NAMESTORE_QueueEntry *qe,
469 /* handle different message type */ 505 /* handle different message type */
470 switch (type) 506 switch (type)
471 { 507 {
472 case GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPONSE: 508 case GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_BLOCK_RESPONSE:
473 if (size < sizeof (struct LookupNameResponseMessage)) 509 if (size < sizeof (struct LookupBlockResponseMessage))
474 { 510 {
475 GNUNET_break (0); 511 GNUNET_break (0);
476 return GNUNET_SYSERR; 512 return GNUNET_SYSERR;
477 } 513 }
478 return handle_lookup_name_response (qe, (const struct LookupNameResponseMessage *) msg, size); 514 return handle_lookup_block_response (qe, (const struct LookupBlockResponseMessage *) msg, size);
479 case GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT_RESPONSE: 515 case GNUNET_MESSAGE_TYPE_NAMESTORE_BLOCK_CACHE_RESPONSE:
480 if (size != sizeof (struct RecordPutResponseMessage)) 516 if (size != sizeof (struct BlockCacheResponseMessage))
481 { 517 {
482 GNUNET_break (0); 518 GNUNET_break (0);
483 return GNUNET_SYSERR; 519 return GNUNET_SYSERR;
484 } 520 }
485 return handle_record_put_response (qe, (const struct RecordPutResponseMessage *) msg, size); 521 return handle_block_cache_response (qe, (const struct BlockCacheResponseMessage *) msg, size);
486 case GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE_RESPONSE: 522 case GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE:
487 if (size != sizeof (struct RecordCreateResponseMessage)) 523 if (size != sizeof (struct RecordStoreResponseMessage))
488 { 524 {
489 GNUNET_break (0); 525 GNUNET_break (0);
490 return GNUNET_SYSERR; 526 return GNUNET_SYSERR;
491 } 527 }
492 return handle_record_create_response (qe, (const struct RecordCreateResponseMessage *) msg, size); 528 return handle_record_store_response (qe, (const struct RecordStoreResponseMessage *) msg, size);
493 case GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE: 529 case GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE:
494 if (size < sizeof (struct ZoneToNameResponseMessage)) 530 if (size < sizeof (struct ZoneToNameResponseMessage))
495 { 531 {
@@ -497,6 +533,13 @@ manage_record_operations (struct GNUNET_NAMESTORE_QueueEntry *qe,
497 return GNUNET_SYSERR; 533 return GNUNET_SYSERR;
498 } 534 }
499 return handle_zone_to_name_response (qe, (const struct ZoneToNameResponseMessage *) msg, size); 535 return handle_zone_to_name_response (qe, (const struct ZoneToNameResponseMessage *) msg, size);
536 case GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT:
537 if (size < sizeof (struct RecordResultMessage))
538 {
539 GNUNET_break (0);
540 return GNUNET_SYSERR;
541 }
542 return handle_record_result (qe, (const struct RecordResultMessage *) msg, size);
500 default: 543 default:
501 GNUNET_break (0); 544 GNUNET_break (0);
502 return GNUNET_SYSERR; 545 return GNUNET_SYSERR;
@@ -515,10 +558,10 @@ manage_record_operations (struct GNUNET_NAMESTORE_QueueEntry *qe,
515 */ 558 */
516static int 559static int
517handle_zone_iteration_response (struct GNUNET_NAMESTORE_ZoneIterator *ze, 560handle_zone_iteration_response (struct GNUNET_NAMESTORE_ZoneIterator *ze,
518 const struct LookupNameResponseMessage *msg, 561 const struct RecordResultMessage *msg,
519 size_t size) 562 size_t size)
520{ 563{
521 struct GNUNET_CRYPTO_EccPublicKey pubdummy; 564 static struct GNUNET_CRYPTO_EccPrivateKey priv_dummy;
522 size_t msg_len; 565 size_t msg_len;
523 size_t exp_msg_len; 566 size_t exp_msg_len;
524 size_t name_len; 567 size_t name_len;
@@ -526,27 +569,25 @@ handle_zone_iteration_response (struct GNUNET_NAMESTORE_ZoneIterator *ze,
526 unsigned rd_count; 569 unsigned rd_count;
527 const char *name_tmp; 570 const char *name_tmp;
528 const char *rd_ser_tmp; 571 const char *rd_ser_tmp;
529 struct GNUNET_TIME_Absolute expire;
530 572
531 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received `%s'\n", 573 LOG (GNUNET_ERROR_TYPE_DEBUG,
574 "Received `%s'\n",
532 "ZONE_ITERATION_RESPONSE"); 575 "ZONE_ITERATION_RESPONSE");
533 msg_len = ntohs (msg->gns_header.header.size); 576 msg_len = ntohs (msg->gns_header.header.size);
534 rd_len = ntohs (msg->rd_len); 577 rd_len = ntohs (msg->rd_len);
535 rd_count = ntohs (msg->rd_count); 578 rd_count = ntohs (msg->rd_count);
536 name_len = ntohs (msg->name_len); 579 name_len = ntohs (msg->name_len);
537 expire = GNUNET_TIME_absolute_ntoh (msg->expire); 580 exp_msg_len = sizeof (struct RecordResultMessage) + name_len + rd_len;
538 exp_msg_len = sizeof (struct LookupNameResponseMessage) + name_len + rd_len;
539 if (msg_len != exp_msg_len) 581 if (msg_len != exp_msg_len)
540 { 582 {
541 GNUNET_break (0); 583 GNUNET_break (0);
542 return GNUNET_SYSERR; 584 return GNUNET_SYSERR;
543 } 585 }
544 memset (&pubdummy, '\0', sizeof (pubdummy)); 586 if ((0 == name_len) && (0 == (memcmp (&msg->private_key, &priv_dummy, sizeof (priv_dummy)))))
545 if ((0 == name_len) && (0 == (memcmp (&msg->public_key, &pubdummy, sizeof (pubdummy)))))
546 { 587 {
547 LOG (GNUNET_ERROR_TYPE_DEBUG, "Zone iteration is completed!\n"); 588 LOG (GNUNET_ERROR_TYPE_DEBUG, "Zone iteration is completed!\n");
548 if (NULL != ze->proc) 589 if (NULL != ze->proc)
549 ze->proc(ze->proc_cls, NULL, GNUNET_TIME_UNIT_ZERO_ABS, NULL , 0, NULL, NULL); 590 ze->proc (ze->proc_cls, NULL, NULL, 0, NULL);
550 return GNUNET_NO; 591 return GNUNET_NO;
551 } 592 }
552 name_tmp = (const char *) &msg[1]; 593 name_tmp = (const char *) &msg[1];
@@ -565,7 +606,7 @@ handle_zone_iteration_response (struct GNUNET_NAMESTORE_ZoneIterator *ze,
565 return GNUNET_SYSERR; 606 return GNUNET_SYSERR;
566 } 607 }
567 if (NULL != ze->proc) 608 if (NULL != ze->proc)
568 ze->proc(ze->proc_cls, &msg->public_key, expire, name_tmp, rd_count, rd, &msg->signature); 609 ze->proc (ze->proc_cls, &msg->private_key, name_tmp, rd_count, rd);
569 return GNUNET_YES; 610 return GNUNET_YES;
570 } 611 }
571} 612}
@@ -589,13 +630,13 @@ manage_zone_operations (struct GNUNET_NAMESTORE_ZoneIterator *ze,
589 /* handle different message type */ 630 /* handle different message type */
590 switch (type) 631 switch (type)
591 { 632 {
592 case GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPONSE: 633 case GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT:
593 if (size < sizeof (struct LookupNameResponseMessage)) 634 if (size < sizeof (struct RecordResultMessage))
594 { 635 {
595 GNUNET_break (0); 636 GNUNET_break (0);
596 return GNUNET_SYSERR; 637 return GNUNET_SYSERR;
597 } 638 }
598 return handle_zone_iteration_response (ze, (const struct LookupNameResponseMessage *) msg, size); 639 return handle_zone_iteration_response (ze, (const struct RecordResultMessage *) msg, size);
599 default: 640 default:
600 GNUNET_break (0); 641 GNUNET_break (0);
601 return GNUNET_SYSERR; 642 return GNUNET_SYSERR;
@@ -611,7 +652,8 @@ manage_zone_operations (struct GNUNET_NAMESTORE_ZoneIterator *ze,
611 * @param msg message received, NULL on timeout or fatal error 652 * @param msg message received, NULL on timeout or fatal error
612 */ 653 */
613static void 654static void
614process_namestore_message (void *cls, const struct GNUNET_MessageHeader *msg) 655process_namestore_message (void *cls,
656 const struct GNUNET_MessageHeader *msg)
615{ 657{
616 struct GNUNET_NAMESTORE_Handle *h = cls; 658 struct GNUNET_NAMESTORE_Handle *h = cls;
617 const struct GNUNET_NAMESTORE_Header *gm; 659 const struct GNUNET_NAMESTORE_Header *gm;
@@ -639,7 +681,8 @@ process_namestore_message (void *cls, const struct GNUNET_MessageHeader *msg)
639 gm = (const struct GNUNET_NAMESTORE_Header *) msg; 681 gm = (const struct GNUNET_NAMESTORE_Header *) msg;
640 r_id = ntohl (gm->r_id); 682 r_id = ntohl (gm->r_id);
641 683
642 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received message type %u size %u op %u\n", 684 LOG (GNUNET_ERROR_TYPE_DEBUG,
685 "Received message type %u size %u op %u\n",
643 (unsigned int) type, 686 (unsigned int) type,
644 (unsigned int) size, 687 (unsigned int) size,
645 (unsigned int) r_id); 688 (unsigned int) r_id);
@@ -737,9 +780,13 @@ transmit_message_to_namestore (void *cls, size_t size, void *buf)
737 ret += p->size; 780 ret += p->size;
738 size -= p->size; 781 size -= p->size;
739 GNUNET_CONTAINER_DLL_remove (h->pending_head, h->pending_tail, p); 782 GNUNET_CONTAINER_DLL_remove (h->pending_head, h->pending_tail, p);
740 if (GNUNET_YES == p->is_init) 783 if (GNUNET_NO == h->is_receiving)
741 GNUNET_CLIENT_receive (h->client, &process_namestore_message, h, 784 {
785 h->is_receiving = GNUNET_YES;
786 GNUNET_CLIENT_receive (h->client,
787 &process_namestore_message, h,
742 GNUNET_TIME_UNIT_FOREVER_REL); 788 GNUNET_TIME_UNIT_FOREVER_REL);
789 }
743 GNUNET_free (p); 790 GNUNET_free (p);
744 } 791 }
745 do_transmit (h); 792 do_transmit (h);
@@ -779,23 +826,9 @@ do_transmit (struct GNUNET_NAMESTORE_Handle *h)
779static void 826static void
780reconnect (struct GNUNET_NAMESTORE_Handle *h) 827reconnect (struct GNUNET_NAMESTORE_Handle *h)
781{ 828{
782 struct PendingMessage *p;
783 struct StartMessage *init;
784
785 GNUNET_assert (NULL == h->client); 829 GNUNET_assert (NULL == h->client);
786 h->client = GNUNET_CLIENT_connect ("namestore", h->cfg); 830 h->client = GNUNET_CLIENT_connect ("namestore", h->cfg);
787 GNUNET_assert (NULL != h->client); 831 GNUNET_assert (NULL != h->client);
788 if ((NULL == (p = h->pending_head)) || (GNUNET_YES != p->is_init))
789 {
790 p = GNUNET_malloc (sizeof (struct PendingMessage) +
791 sizeof (struct StartMessage));
792 p->size = sizeof (struct StartMessage);
793 p->is_init = GNUNET_YES;
794 init = (struct StartMessage *) &p[1];
795 init->header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_START);
796 init->header.size = htons (sizeof (struct StartMessage));
797 GNUNET_CONTAINER_DLL_insert (h->pending_head, h->pending_tail, p);
798 }
799 do_transmit (h); 832 do_transmit (h);
800} 833}
801 834
@@ -826,6 +859,7 @@ force_reconnect (struct GNUNET_NAMESTORE_Handle *h)
826{ 859{
827 h->reconnect = GNUNET_NO; 860 h->reconnect = GNUNET_NO;
828 GNUNET_CLIENT_disconnect (h->client); 861 GNUNET_CLIENT_disconnect (h->client);
862 h->is_receiving = GNUNET_NO;
829 h->client = NULL; 863 h->client = NULL;
830 h->reconnect_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, 864 h->reconnect_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
831 &reconnect_task, 865 &reconnect_task,
@@ -857,7 +891,7 @@ GNUNET_NAMESTORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
857{ 891{
858 struct GNUNET_NAMESTORE_Handle *h; 892 struct GNUNET_NAMESTORE_Handle *h;
859 893
860 h = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_Handle)); 894 h = GNUNET_new (struct GNUNET_NAMESTORE_Handle);
861 h->cfg = cfg; 895 h->cfg = cfg;
862 h->reconnect_task = GNUNET_SCHEDULER_add_now (&reconnect_task, h); 896 h->reconnect_task = GNUNET_SCHEDULER_add_now (&reconnect_task, h);
863 h->last_op_id_used = 0; 897 h->last_op_id_used = 0;
@@ -913,60 +947,31 @@ GNUNET_NAMESTORE_disconnect (struct GNUNET_NAMESTORE_Handle *h)
913 947
914/** 948/**
915 * Store an item in the namestore. If the item is already present, 949 * Store an item in the namestore. If the item is already present,
916 * the expiration time is updated to the max of the existing time and 950 * it is replaced with the new record.
917 * the new time. This API is used when we cache signatures from other
918 * authorities.
919 * 951 *
920 * @param h handle to the namestore 952 * @param h handle to the namestore
921 * @param zone_key public key of the zone 953 * @param block block to store
922 * @param name name that is being mapped (at most 255 characters long)
923 * @param freshness when does the corresponding block in the DHT expire (until
924 * when should we never do a DHT lookup for the same name again)?
925 * @param rd_count number of entries in 'rd' array
926 * @param rd array of records with data to store
927 * @param signature signature for all the records in the zone under the given name
928 * @param cont continuation to call when done 954 * @param cont continuation to call when done
929 * @param cont_cls closure for cont 955 * @param cont_cls closure for cont
930 * @return handle to abort the request 956 * @return handle to abort the request
931 */ 957 */
932struct GNUNET_NAMESTORE_QueueEntry * 958struct GNUNET_NAMESTORE_QueueEntry *
933GNUNET_NAMESTORE_record_put (struct GNUNET_NAMESTORE_Handle *h, 959GNUNET_NAMESTORE_block_cache (struct GNUNET_NAMESTORE_Handle *h,
934 const struct GNUNET_CRYPTO_EccPublicKey *zone_key, 960 const struct GNUNET_NAMESTORE_Block *block,
935 const char *name, 961 GNUNET_NAMESTORE_ContinuationWithStatus cont,
936 struct GNUNET_TIME_Absolute freshness, 962 void *cont_cls)
937 unsigned int rd_count,
938 const struct GNUNET_NAMESTORE_RecordData *rd,
939 const struct GNUNET_CRYPTO_EccSignature *signature,
940 GNUNET_NAMESTORE_ContinuationWithStatus cont,
941 void *cont_cls)
942{ 963{
943 struct GNUNET_NAMESTORE_QueueEntry *qe; 964 struct GNUNET_NAMESTORE_QueueEntry *qe;
944 struct PendingMessage *pe; 965 struct PendingMessage *pe;
945 struct RecordPutMessage * msg; 966 struct BlockCacheMessage *msg;
946 char * rd_ser;
947 char * name_tmp;
948 size_t msg_size;
949 size_t name_len;
950 size_t rd_ser_len;
951 uint32_t rid; 967 uint32_t rid;
968 size_t blen;
969 size_t msg_size;
952 970
953 GNUNET_assert (NULL != h); 971 GNUNET_assert (NULL != h);
954 GNUNET_assert (NULL != zone_key); 972 blen = ntohl (block->purpose.size) - sizeof (struct GNUNET_TIME_AbsoluteNBO);
955 GNUNET_assert (NULL != name);
956 GNUNET_assert (NULL != rd);
957 GNUNET_assert (NULL != signature);
958 LOG (GNUNET_ERROR_TYPE_DEBUG,
959 "Storing %u records under name `%s'\n",
960 rd_count,
961 name);
962 name_len = strlen(name) + 1;
963 if (name_len > MAX_NAME_LEN)
964 {
965 GNUNET_break (0);
966 return NULL;
967 }
968 rid = get_op_id (h); 973 rid = get_op_id (h);
969 qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry)); 974 qe = GNUNET_new (struct GNUNET_NAMESTORE_QueueEntry);
970 qe->nsh = h; 975 qe->nsh = h;
971 qe->cont = cont; 976 qe->cont = cont;
972 qe->cont_cls = cont_cls; 977 qe->cont_cls = cont_cls;
@@ -974,29 +979,21 @@ GNUNET_NAMESTORE_record_put (struct GNUNET_NAMESTORE_Handle *h,
974 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, qe); 979 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, qe);
975 980
976 /* setup msg */ 981 /* setup msg */
977 rd_ser_len = GNUNET_NAMESTORE_records_get_size(rd_count, rd); 982 msg_size = sizeof (struct BlockCacheMessage) + blen;
978 msg_size = sizeof (struct RecordPutMessage) + name_len + rd_ser_len; 983 pe = GNUNET_malloc (sizeof (struct PendingMessage) + msg_size);
979 pe = GNUNET_malloc(sizeof (struct PendingMessage) + msg_size);
980 pe->size = msg_size; 984 pe->size = msg_size;
981 pe->is_init = GNUNET_NO; 985 msg = (struct BlockCacheMessage *) &pe[1];
982 msg = (struct RecordPutMessage *) &pe[1]; 986 msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_BLOCK_CACHE);
983 msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT);
984 msg->gns_header.header.size = htons (msg_size); 987 msg->gns_header.header.size = htons (msg_size);
985 msg->gns_header.r_id = htonl (rid); 988 msg->gns_header.r_id = htonl (rid);
986 msg->signature = *signature; 989 msg->expire = block->expiration_time;
987 msg->name_len = htons (name_len); 990 msg->signature = block->signature;
988 msg->expire = GNUNET_TIME_absolute_hton (freshness); 991 msg->derived_key = block->derived_key;
989 msg->rd_len = htons (rd_ser_len); 992 memcpy (&msg[1], &block[1], blen);
990 msg->rd_count = htons (rd_count);
991 msg->public_key = *zone_key;
992 name_tmp = (char *) &msg[1];
993 memcpy (name_tmp, name, name_len);
994 rd_ser = &name_tmp[name_len];
995 GNUNET_break (rd_ser_len == GNUNET_NAMESTORE_records_serialize (rd_count, rd, rd_ser_len, rd_ser));
996 LOG (GNUNET_ERROR_TYPE_DEBUG, 993 LOG (GNUNET_ERROR_TYPE_DEBUG,
997 "Sending `%s' message for name `%s' with size %u\n", 994 "Sending `%s' message with size %u\n",
998 "NAMESTORE_RECORD_PUT", 995 "NAMESTORE_BLOCK_CACHE",
999 name, msg_size); 996 (unsigned int) msg_size);
1000 GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe); 997 GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
1001 do_transmit(h); 998 do_transmit(h);
1002 return qe; 999 return qe;
@@ -1004,86 +1001,27 @@ GNUNET_NAMESTORE_record_put (struct GNUNET_NAMESTORE_Handle *h,
1004 1001
1005 1002
1006/** 1003/**
1007 * Check if a signature is valid. This API is used by the GNS Block
1008 * to validate signatures received from the network.
1009 *
1010 * @param public_key public key of the zone
1011 * @param freshness block expiration
1012 * @param name name that is being mapped (at most 255 characters long)
1013 * @param rd_count number of entries in 'rd' array
1014 * @param rd array of records with data to store
1015 * @param signature signature for all the records in the zone under the given name
1016 * @return GNUNET_OK if the signature is valid
1017 */
1018int
1019GNUNET_NAMESTORE_verify_signature (const struct GNUNET_CRYPTO_EccPublicKey *public_key,
1020 const struct GNUNET_TIME_Absolute freshness,
1021 const char *name,
1022 unsigned int rd_count,
1023 const struct GNUNET_NAMESTORE_RecordData *rd,
1024 const struct GNUNET_CRYPTO_EccSignature *signature)
1025{
1026 size_t rd_ser_len;
1027 size_t name_len;
1028 char *name_tmp;
1029 char *rd_ser;
1030 struct GNUNET_CRYPTO_EccSignaturePurpose *sig_purpose;
1031 struct GNUNET_TIME_AbsoluteNBO *expire_tmp;
1032 struct GNUNET_TIME_AbsoluteNBO expire_nbo = GNUNET_TIME_absolute_hton (freshness);
1033 uint32_t sig_len;
1034
1035 GNUNET_assert (NULL != public_key);
1036 GNUNET_assert (NULL != name);
1037 GNUNET_assert (NULL != rd);
1038 GNUNET_assert (NULL != signature);
1039 name_len = strlen (name) + 1;
1040 if (name_len > MAX_NAME_LEN)
1041 {
1042 GNUNET_break (0);
1043 return GNUNET_SYSERR;
1044 }
1045 rd_ser_len = GNUNET_NAMESTORE_records_get_size (rd_count, rd);
1046 sig_len = sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + sizeof (struct GNUNET_TIME_AbsoluteNBO) + rd_ser_len + name_len;
1047 {
1048 char sig_buf[sig_len] GNUNET_ALIGN;
1049
1050 sig_purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose *) sig_buf;
1051 sig_purpose->size = htonl (sig_len);
1052 sig_purpose->purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
1053 expire_tmp = (struct GNUNET_TIME_AbsoluteNBO *) &sig_purpose[1];
1054 memcpy (expire_tmp, &expire_nbo, sizeof (struct GNUNET_TIME_AbsoluteNBO));
1055 name_tmp = (char *) &expire_tmp[1];
1056 memcpy (name_tmp, name, name_len);
1057 rd_ser = &name_tmp[name_len];
1058 GNUNET_assert (rd_ser_len ==
1059 GNUNET_NAMESTORE_records_serialize (rd_count, rd, rd_ser_len, rd_ser));
1060 return GNUNET_CRYPTO_ecc_verify (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN, sig_purpose, signature, public_key);
1061 }
1062}
1063
1064
1065/**
1066 * Store an item in the namestore. If the item is already present, 1004 * Store an item in the namestore. If the item is already present,
1067 * the expiration time is updated to the max of the existing time and 1005 * it is replaced with the new record. Use an empty array to
1068 * the new time. This API is used by the authority of a zone. 1006 * remove all records under the given name.
1069 * 1007 *
1070 * @param h handle to the namestore 1008 * @param h handle to the namestore
1071 * @param pkey private key of the zone 1009 * @param pkey private key of the zone
1072 * @param name name that is being mapped (at most 255 characters long) 1010 * @param label name that is being mapped (at most 255 characters long)
1073 * @param rd_count number of records in 'rd' array 1011 * @param rd_count number of records in the 'rd' array
1074 * @param rd record data to store 1012 * @param rd array of records with data to store
1075 * @param cont continuation to call when done 1013 * @param cont continuation to call when done
1076 * @param cont_cls closure for cont 1014 * @param cont_cls closure for 'cont'
1077 * @return handle to abort the request 1015 * @return handle to abort the request
1078 */ 1016 */
1079struct GNUNET_NAMESTORE_QueueEntry * 1017struct GNUNET_NAMESTORE_QueueEntry *
1080GNUNET_NAMESTORE_record_put_by_authority (struct GNUNET_NAMESTORE_Handle *h, 1018GNUNET_NAMESTORE_records_store (struct GNUNET_NAMESTORE_Handle *h,
1081 const struct GNUNET_CRYPTO_EccPrivateKey *pkey, 1019 const struct GNUNET_CRYPTO_EccPrivateKey *pkey,
1082 const char *name, 1020 const char *label,
1083 unsigned int rd_count, 1021 unsigned int rd_count,
1084 const struct GNUNET_NAMESTORE_RecordData *rd, 1022 const struct GNUNET_NAMESTORE_RecordData *rd,
1085 GNUNET_NAMESTORE_ContinuationWithStatus cont, 1023 GNUNET_NAMESTORE_ContinuationWithStatus cont,
1086 void *cont_cls) 1024 void *cont_cls)
1087{ 1025{
1088 struct GNUNET_NAMESTORE_QueueEntry *qe; 1026 struct GNUNET_NAMESTORE_QueueEntry *qe;
1089 struct PendingMessage *pe; 1027 struct PendingMessage *pe;
@@ -1093,19 +1031,19 @@ GNUNET_NAMESTORE_record_put_by_authority (struct GNUNET_NAMESTORE_Handle *h,
1093 size_t msg_size; 1031 size_t msg_size;
1094 size_t name_len; 1032 size_t name_len;
1095 uint32_t rid; 1033 uint32_t rid;
1096 struct RecordCreateMessage *msg; 1034 struct RecordStoreMessage *msg;
1097 1035
1098 GNUNET_assert (NULL != h); 1036 GNUNET_assert (NULL != h);
1099 GNUNET_assert (NULL != pkey); 1037 GNUNET_assert (NULL != pkey);
1100 GNUNET_assert (NULL != name); 1038 GNUNET_assert (NULL != label);
1101 name_len = strlen(name) + 1; 1039 name_len = strlen (label) + 1;
1102 if (name_len > MAX_NAME_LEN) 1040 if (name_len > MAX_NAME_LEN)
1103 { 1041 {
1104 GNUNET_break (0); 1042 GNUNET_break (0);
1105 return NULL; 1043 return NULL;
1106 } 1044 }
1107 rid = get_op_id (h); 1045 rid = get_op_id (h);
1108 qe = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_QueueEntry)); 1046 qe = GNUNET_new (struct GNUNET_NAMESTORE_QueueEntry);
1109 qe->nsh = h; 1047 qe->nsh = h;
1110 qe->cont = cont; 1048 qe->cont = cont;
1111 qe->cont_cls = cont_cls; 1049 qe->cont_cls = cont_cls;
@@ -1114,29 +1052,27 @@ GNUNET_NAMESTORE_record_put_by_authority (struct GNUNET_NAMESTORE_Handle *h,
1114 1052
1115 /* setup msg */ 1053 /* setup msg */
1116 rd_ser_len = GNUNET_NAMESTORE_records_get_size (rd_count, rd); 1054 rd_ser_len = GNUNET_NAMESTORE_records_get_size (rd_count, rd);
1117 msg_size = sizeof (struct RecordCreateMessage) + name_len + rd_ser_len; 1055 msg_size = sizeof (struct RecordStoreMessage) + name_len + rd_ser_len;
1118 pe = GNUNET_malloc (sizeof (struct PendingMessage) + msg_size); 1056 pe = GNUNET_malloc (sizeof (struct PendingMessage) + msg_size);
1119 pe->size = msg_size; 1057 pe->size = msg_size;
1120 pe->is_init = GNUNET_NO; 1058 msg = (struct RecordStoreMessage *) &pe[1];
1121 msg = (struct RecordCreateMessage *) &pe[1]; 1059 msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE);
1122 msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_CREATE);
1123 msg->gns_header.header.size = htons (msg_size); 1060 msg->gns_header.header.size = htons (msg_size);
1124 msg->gns_header.r_id = htonl (rid); 1061 msg->gns_header.r_id = htonl (rid);
1125 msg->name_len = htons (name_len); 1062 msg->name_len = htons (name_len);
1126 msg->rd_count = htons (rd_count); 1063 msg->rd_count = htons (rd_count);
1127 msg->rd_len = htons (rd_ser_len); 1064 msg->rd_len = htons (rd_ser_len);
1128 msg->reserved = htons (0); 1065 msg->reserved = htons (0);
1129 msg->expire = GNUNET_TIME_absolute_hton (GNUNET_TIME_UNIT_FOREVER_ABS);
1130 msg->private_key = *pkey; 1066 msg->private_key = *pkey;
1131 1067
1132 name_tmp = (char *) &msg[1]; 1068 name_tmp = (char *) &msg[1];
1133 memcpy (name_tmp, name, name_len); 1069 memcpy (name_tmp, label, name_len);
1134 rd_ser = &name_tmp[name_len]; 1070 rd_ser = &name_tmp[name_len];
1135 GNUNET_break (rd_ser_len == GNUNET_NAMESTORE_records_serialize (rd_count, rd, rd_ser_len, rd_ser)); 1071 GNUNET_break (rd_ser_len == GNUNET_NAMESTORE_records_serialize (rd_count, rd, rd_ser_len, rd_ser));
1136 1072
1137 LOG (GNUNET_ERROR_TYPE_DEBUG, 1073 LOG (GNUNET_ERROR_TYPE_DEBUG,
1138 "Sending `%s' message for name `%s' with size %u\n", 1074 "Sending `%s' message for name `%s' with size %u\n",
1139 "NAMESTORE_RECORD_CREATE", name, msg_size); 1075 "NAMESTORE_RECORD_STORE", label, msg_size);
1140 GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe); 1076 GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
1141 do_transmit(h); 1077 do_transmit(h);
1142 return qe; 1078 return qe;
@@ -1148,66 +1084,45 @@ GNUNET_NAMESTORE_record_put_by_authority (struct GNUNET_NAMESTORE_Handle *h,
1148 * will only be called once. 1084 * will only be called once.
1149 * 1085 *
1150 * @param h handle to the namestore 1086 * @param h handle to the namestore
1151 * @param zone zone to look up a record from 1087 * @param derived_hash hash of zone key combined with name to lookup
1152 * @param name name to look up 1088 * @param proc function to call on the matching block, or with
1153 * @param record_type desired record type, 0 for all 1089 * NULL if there is no matching block
1154 * @param proc function to call on the matching records, or with
1155 * NULL (rd_count == 0) if there are no matching records
1156 * @param proc_cls closure for proc 1090 * @param proc_cls closure for proc
1157 * @return a handle that can be used to 1091 * @return a handle that can be used to cancel
1158 * cancel
1159 */ 1092 */
1160struct GNUNET_NAMESTORE_QueueEntry * 1093struct GNUNET_NAMESTORE_QueueEntry *
1161GNUNET_NAMESTORE_lookup_record (struct GNUNET_NAMESTORE_Handle *h, 1094GNUNET_NAMESTORE_lookup_block (struct GNUNET_NAMESTORE_Handle *h,
1162 const struct GNUNET_CRYPTO_ShortHashCode *zone, 1095 const struct GNUNET_HashCode *derived_hash,
1163 const char *name, 1096 GNUNET_NAMESTORE_BlockProcessor proc, void *proc_cls)
1164 uint32_t record_type,
1165 GNUNET_NAMESTORE_RecordProcessor proc, void *proc_cls)
1166{ 1097{
1098
1167 struct GNUNET_NAMESTORE_QueueEntry *qe; 1099 struct GNUNET_NAMESTORE_QueueEntry *qe;
1168 struct PendingMessage *pe; 1100 struct PendingMessage *pe;
1169 struct LookupNameMessage * msg; 1101 struct LookupBlockMessage *msg;
1170 size_t msg_size; 1102 size_t msg_size;
1171 size_t name_len;
1172 uint32_t rid; 1103 uint32_t rid;
1173 1104
1174 GNUNET_assert (NULL != h); 1105 GNUNET_assert (NULL != h);
1175 GNUNET_assert (NULL != zone); 1106 GNUNET_assert (NULL != derived_hash);
1176 GNUNET_assert (NULL != name);
1177 LOG (GNUNET_ERROR_TYPE_DEBUG, 1107 LOG (GNUNET_ERROR_TYPE_DEBUG,
1178 "Looking for record of type %u under name `%s'\n", 1108 "Looking for block under %s\n",
1179 record_type, 1109 GNUNET_h2s (derived_hash));
1180 name);
1181 name_len = strlen (name) + 1;
1182 if ((name_len == 0) || (name_len > MAX_NAME_LEN))
1183 {
1184 GNUNET_break (0);
1185 return NULL;
1186 }
1187
1188 rid = get_op_id(h); 1110 rid = get_op_id(h);
1189 qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry)); 1111 qe = GNUNET_new (struct GNUNET_NAMESTORE_QueueEntry);
1190 qe->nsh = h; 1112 qe->nsh = h;
1191 qe->proc = proc; 1113 qe->block_proc = proc;
1192 qe->proc_cls = proc_cls; 1114 qe->block_proc_cls = proc_cls;
1193 qe->op_id = rid; 1115 qe->op_id = rid;
1194 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, qe); 1116 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, qe);
1195 1117
1196 msg_size = sizeof (struct LookupNameMessage) + name_len; 1118 msg_size = sizeof (struct LookupBlockMessage);
1197 pe = GNUNET_malloc(sizeof (struct PendingMessage) + msg_size); 1119 pe = GNUNET_malloc (sizeof (struct PendingMessage) + msg_size);
1198 pe->size = msg_size; 1120 pe->size = msg_size;
1199 pe->is_init = GNUNET_NO; 1121 msg = (struct LookupBlockMessage *) &pe[1];
1200 msg = (struct LookupNameMessage *) &pe[1]; 1122 msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_BLOCK);
1201 msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME);
1202 msg->gns_header.header.size = htons (msg_size); 1123 msg->gns_header.header.size = htons (msg_size);
1203 msg->gns_header.r_id = htonl (rid); 1124 msg->gns_header.r_id = htonl (rid);
1204 msg->record_type = htonl (record_type); 1125 msg->query = *derived_hash;
1205 msg->name_len = htonl (name_len);
1206 msg->zone = *zone;
1207 memcpy (&msg[1], name, name_len);
1208
1209 LOG (GNUNET_ERROR_TYPE_DEBUG,
1210 "Sending `%s' message for name `%s'\n", "NAMESTORE_LOOKUP_NAME", name);
1211 GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe); 1126 GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
1212 do_transmit(h); 1127 do_transmit(h);
1213 return qe; 1128 return qe;
@@ -1219,8 +1134,8 @@ GNUNET_NAMESTORE_lookup_record (struct GNUNET_NAMESTORE_Handle *h,
1219 * Returns at most one result to the processor. 1134 * Returns at most one result to the processor.
1220 * 1135 *
1221 * @param h handle to the namestore 1136 * @param h handle to the namestore
1222 * @param zone hash of public key of the zone to look up in, never NULL 1137 * @param zone public key of the zone to look up in, never NULL
1223 * @param value_zone hash of the public key of the target zone (value), never NULL 1138 * @param value_zone public key of the target zone (value), never NULL
1224 * @param proc function to call on the matching records, or with 1139 * @param proc function to call on the matching records, or with
1225 * NULL (rd_count == 0) if there are no matching records 1140 * NULL (rd_count == 0) if there are no matching records
1226 * @param proc_cls closure for proc 1141 * @param proc_cls closure for proc
@@ -1229,9 +1144,9 @@ GNUNET_NAMESTORE_lookup_record (struct GNUNET_NAMESTORE_Handle *h,
1229 */ 1144 */
1230struct GNUNET_NAMESTORE_QueueEntry * 1145struct GNUNET_NAMESTORE_QueueEntry *
1231GNUNET_NAMESTORE_zone_to_name (struct GNUNET_NAMESTORE_Handle *h, 1146GNUNET_NAMESTORE_zone_to_name (struct GNUNET_NAMESTORE_Handle *h,
1232 const struct GNUNET_CRYPTO_ShortHashCode *zone, 1147 const struct GNUNET_CRYPTO_EccPrivateKey *zone,
1233 const struct GNUNET_CRYPTO_ShortHashCode *value_zone, 1148 const struct GNUNET_CRYPTO_EccPublicKey *value_zone,
1234 GNUNET_NAMESTORE_RecordProcessor proc, void *proc_cls) 1149 GNUNET_NAMESTORE_RecordMonitor proc, void *proc_cls)
1235{ 1150{
1236 struct GNUNET_NAMESTORE_QueueEntry *qe; 1151 struct GNUNET_NAMESTORE_QueueEntry *qe;
1237 struct PendingMessage *pe; 1152 struct PendingMessage *pe;
@@ -1243,7 +1158,7 @@ GNUNET_NAMESTORE_zone_to_name (struct GNUNET_NAMESTORE_Handle *h,
1243 GNUNET_assert (NULL != zone); 1158 GNUNET_assert (NULL != zone);
1244 GNUNET_assert (NULL != value_zone); 1159 GNUNET_assert (NULL != value_zone);
1245 rid = get_op_id(h); 1160 rid = get_op_id(h);
1246 qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry)); 1161 qe = GNUNET_new (struct GNUNET_NAMESTORE_QueueEntry);
1247 qe->nsh = h; 1162 qe->nsh = h;
1248 qe->proc = proc; 1163 qe->proc = proc;
1249 qe->proc_cls = proc_cls; 1164 qe->proc_cls = proc_cls;
@@ -1251,9 +1166,8 @@ GNUNET_NAMESTORE_zone_to_name (struct GNUNET_NAMESTORE_Handle *h,
1251 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, qe); 1166 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, qe);
1252 1167
1253 msg_size = sizeof (struct ZoneToNameMessage); 1168 msg_size = sizeof (struct ZoneToNameMessage);
1254 pe = GNUNET_malloc(sizeof (struct PendingMessage) + msg_size); 1169 pe = GNUNET_malloc (sizeof (struct PendingMessage) + msg_size);
1255 pe->size = msg_size; 1170 pe->size = msg_size;
1256 pe->is_init = GNUNET_NO;
1257 msg = (struct ZoneToNameMessage *) &pe[1]; 1171 msg = (struct ZoneToNameMessage *) &pe[1];
1258 msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME); 1172 msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME);
1259 msg->gns_header.header.size = htons (msg_size); 1173 msg->gns_header.header.size = htons (msg_size);
@@ -1277,9 +1191,7 @@ GNUNET_NAMESTORE_zone_to_name (struct GNUNET_NAMESTORE_Handle *h,
1277 * "GNUNET_NAMESTORE_zone_iterator_next" is invoked. 1191 * "GNUNET_NAMESTORE_zone_iterator_next" is invoked.
1278 * 1192 *
1279 * @param h handle to the namestore 1193 * @param h handle to the namestore
1280 * @param zone zone to access, NULL for all zones 1194 * @param zone zone to access
1281 * @param must_have_flags flags that must be set for the record to be returned
1282 * @param must_not_have_flags flags that must NOT be set for the record to be returned
1283 * @param proc function to call on each name from the zone; it 1195 * @param proc function to call on each name from the zone; it
1284 * will be called repeatedly with a value (if available) 1196 * will be called repeatedly with a value (if available)
1285 * and always once at the end with a name of NULL. 1197 * and always once at the end with a name of NULL.
@@ -1288,10 +1200,8 @@ GNUNET_NAMESTORE_zone_to_name (struct GNUNET_NAMESTORE_Handle *h,
1288 */ 1200 */
1289struct GNUNET_NAMESTORE_ZoneIterator * 1201struct GNUNET_NAMESTORE_ZoneIterator *
1290GNUNET_NAMESTORE_zone_iteration_start (struct GNUNET_NAMESTORE_Handle *h, 1202GNUNET_NAMESTORE_zone_iteration_start (struct GNUNET_NAMESTORE_Handle *h,
1291 const struct GNUNET_CRYPTO_ShortHashCode *zone, 1203 const struct GNUNET_CRYPTO_EccPrivateKey *zone,
1292 enum GNUNET_NAMESTORE_RecordFlags must_have_flags, 1204 GNUNET_NAMESTORE_RecordMonitor proc,
1293 enum GNUNET_NAMESTORE_RecordFlags must_not_have_flags,
1294 GNUNET_NAMESTORE_RecordProcessor proc,
1295 void *proc_cls) 1205 void *proc_cls)
1296{ 1206{
1297 struct GNUNET_NAMESTORE_ZoneIterator *it; 1207 struct GNUNET_NAMESTORE_ZoneIterator *it;
@@ -1302,46 +1212,22 @@ GNUNET_NAMESTORE_zone_iteration_start (struct GNUNET_NAMESTORE_Handle *h,
1302 1212
1303 GNUNET_assert (NULL != h); 1213 GNUNET_assert (NULL != h);
1304 rid = get_op_id(h); 1214 rid = get_op_id(h);
1305 it = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_ZoneIterator)); 1215 it = GNUNET_new (struct GNUNET_NAMESTORE_ZoneIterator);
1306 it->h = h; 1216 it->h = h;
1307 it->proc = proc; 1217 it->proc = proc;
1308 it->proc_cls = proc_cls; 1218 it->proc_cls = proc_cls;
1309 it->op_id = rid; 1219 it->op_id = rid;
1310 if (NULL != zone) 1220 it->zone = *zone;
1311 {
1312 it->zone = *zone;
1313 it->has_zone = GNUNET_YES;
1314 }
1315 else
1316 {
1317 memset (&it->zone, '\0', sizeof (it->zone));
1318 it->has_zone = GNUNET_NO;
1319 }
1320 GNUNET_CONTAINER_DLL_insert_tail (h->z_head, h->z_tail, it); 1221 GNUNET_CONTAINER_DLL_insert_tail (h->z_head, h->z_tail, it);
1321 1222
1322 msg_size = sizeof (struct ZoneIterationStartMessage); 1223 msg_size = sizeof (struct ZoneIterationStartMessage);
1323 pe = GNUNET_malloc (sizeof (struct PendingMessage) + msg_size); 1224 pe = GNUNET_malloc (sizeof (struct PendingMessage) + msg_size);
1324 pe->size = msg_size; 1225 pe->size = msg_size;
1325 pe->is_init = GNUNET_NO;
1326 msg = (struct ZoneIterationStartMessage *) &pe[1]; 1226 msg = (struct ZoneIterationStartMessage *) &pe[1];
1327 msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START); 1227 msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START);
1328 msg->gns_header.header.size = htons (msg_size); 1228 msg->gns_header.header.size = htons (msg_size);
1329 msg->gns_header.r_id = htonl (rid); 1229 msg->gns_header.r_id = htonl (rid);
1330 if (NULL != zone) 1230 msg->zone = *zone;
1331 {
1332 LOG (GNUNET_ERROR_TYPE_DEBUG,
1333 "Sending `%s' message for zone `%s'\n",
1334 "ZONE_ITERATION_START", GNUNET_NAMESTORE_short_h2s(zone));
1335 msg->zone = *zone;
1336 }
1337 else
1338 {
1339 LOG (GNUNET_ERROR_TYPE_DEBUG,
1340 "Sending `%s' message for all zones\n", "ZONE_ITERATION_START");
1341 memset (&msg->zone, '\0', sizeof (msg->zone));
1342 }
1343 msg->must_have_flags = ntohs (must_have_flags);
1344 msg->must_not_have_flags = ntohs (must_not_have_flags);
1345 GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe); 1231 GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
1346 do_transmit(h); 1232 do_transmit(h);
1347 return it; 1233 return it;
@@ -1365,9 +1251,8 @@ GNUNET_NAMESTORE_zone_iterator_next (struct GNUNET_NAMESTORE_ZoneIterator *it)
1365 GNUNET_assert (NULL != it); 1251 GNUNET_assert (NULL != it);
1366 h = it->h; 1252 h = it->h;
1367 msg_size = sizeof (struct ZoneIterationNextMessage); 1253 msg_size = sizeof (struct ZoneIterationNextMessage);
1368 pe = GNUNET_malloc(sizeof (struct PendingMessage) + msg_size); 1254 pe = GNUNET_malloc (sizeof (struct PendingMessage) + msg_size);
1369 pe->size = msg_size; 1255 pe->size = msg_size;
1370 pe->is_init = GNUNET_NO;
1371 msg = (struct ZoneIterationNextMessage *) &pe[1]; 1256 msg = (struct ZoneIterationNextMessage *) &pe[1];
1372 msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT); 1257 msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT);
1373 msg->gns_header.header.size = htons (msg_size); 1258 msg->gns_header.header.size = htons (msg_size);
@@ -1397,19 +1282,15 @@ GNUNET_NAMESTORE_zone_iteration_stop (struct GNUNET_NAMESTORE_ZoneIterator *it)
1397 h->z_tail, 1282 h->z_tail,
1398 it); 1283 it);
1399 msg_size = sizeof (struct ZoneIterationStopMessage); 1284 msg_size = sizeof (struct ZoneIterationStopMessage);
1400 pe = GNUNET_malloc(sizeof (struct PendingMessage) + msg_size); 1285 pe = GNUNET_malloc (sizeof (struct PendingMessage) + msg_size);
1401 pe->size = msg_size; 1286 pe->size = msg_size;
1402 pe->is_init = GNUNET_NO;
1403 msg = (struct ZoneIterationStopMessage *) &pe[1]; 1287 msg = (struct ZoneIterationStopMessage *) &pe[1];
1404 msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP); 1288 msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP);
1405 msg->gns_header.header.size = htons (msg_size); 1289 msg->gns_header.header.size = htons (msg_size);
1406 msg->gns_header.r_id = htonl (it->op_id); 1290 msg->gns_header.r_id = htonl (it->op_id);
1407 if (GNUNET_YES == it->has_zone) 1291 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1408 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1292 "Sending `%s' message\n",
1409 "Sending `%s' message for zone `%s'\n", "ZONE_ITERATION_STOP", GNUNET_NAMESTORE_short_h2s(&it->zone)); 1293 "ZONE_ITERATION_STOP");
1410 else
1411 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1412 "Sending `%s' message for all zones\n", "ZONE_ITERATION_STOP");
1413 GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe); 1294 GNUNET_CONTAINER_DLL_insert_tail (h->pending_head, h->pending_tail, pe);
1414 do_transmit(h); 1295 do_transmit(h);
1415 GNUNET_free (it); 1296 GNUNET_free (it);
diff --git a/src/namestore/namestore_api_common.c b/src/namestore/namestore_api_common.c
index 7098e6131..b2cd80013 100644
--- a/src/namestore/namestore_api_common.c
+++ b/src/namestore/namestore_api_common.c
@@ -23,6 +23,7 @@
23 * @brief API to access the NAMESTORE service 23 * @brief API to access the NAMESTORE service
24 * @author Martin Schanzenbach 24 * @author Martin Schanzenbach
25 * @author Matthias Wachs 25 * @author Matthias Wachs
26 * @author Christian Grothoff
26 */ 27 */
27 28
28#include "platform.h" 29#include "platform.h"
@@ -40,6 +41,7 @@
40 41
41GNUNET_NETWORK_STRUCT_BEGIN 42GNUNET_NETWORK_STRUCT_BEGIN
42 43
44
43/** 45/**
44 * Internal format of a record in the serialized form. 46 * Internal format of a record in the serialized form.
45 */ 47 */
@@ -88,20 +90,29 @@ GNUNET_NAMESTORE_normalize_string (const char *src)
88 90
89 91
90/** 92/**
91 * Convert a short hash to a string (for printing debug messages). 93 * Convert a zone key to a string (for printing debug messages).
92 * This is one of the very few calls in the entire API that is 94 * This is one of the very few calls in the entire API that is
93 * NOT reentrant! 95 * NOT reentrant!
94 * 96 *
95 * @param hc the short hash code 97 * @param z the zone key
96 * @return string form; will be overwritten by next call to GNUNET_h2s. 98 * @return string form; will be overwritten by next call to GNUNET_NAMESTORE_z2s
97 */ 99 */
98const char * 100const char *
99GNUNET_NAMESTORE_short_h2s (const struct GNUNET_CRYPTO_ShortHashCode * hc) 101GNUNET_NAMESTORE_z2s (const struct GNUNET_CRYPTO_EccPublicKey *z)
100{ 102{
101 static struct GNUNET_CRYPTO_ShortHashAsciiEncoded ret; 103 static char buf[sizeof (struct GNUNET_CRYPTO_EccPublicKey) * 8];
104 char *end;
102 105
103 GNUNET_CRYPTO_short_hash_to_enc (hc, &ret); 106 end = GNUNET_STRINGS_data_to_string ((const unsigned char *) z,
104 return (const char *) &ret; 107 sizeof (struct GNUNET_CRYPTO_EccPublicKey),
108 buf, sizeof (buf));
109 if (NULL == end)
110 {
111 GNUNET_break (0);
112 return NULL;
113 }
114 *end = '\0';
115 return buf;
105} 116}
106 117
107 118
@@ -273,20 +284,82 @@ GNUNET_NAMESTORE_records_deserialize (size_t len,
273 * 284 *
274 * @param key the private key 285 * @param key the private key
275 * @param expire block expiration 286 * @param expire block expiration
276 * @param name the name 287 * @param label the name for the records
277 * @param rd record data 288 * @param rd record data
278 * @param rd_count number of records 289 * @param rd_count number of records
290 * @param signature where to store the signature
291 */
292struct GNUNET_NAMESTORE_Block *
293GNUNET_NAMESTORE_block_create (const struct GNUNET_CRYPTO_EccPrivateKey *key,
294 struct GNUNET_TIME_Absolute expire,
295 const char *label,
296 const struct GNUNET_NAMESTORE_RecordData *rd,
297 unsigned int rd_count)
298{
299 GNUNET_break (0);
300 return NULL;
301}
302
303
304/**
305 * Check if a signature is valid. This API is used by the GNS Block
306 * to validate signatures received from the network.
307 *
308 * @param block block to verify
309 * @return GNUNET_OK if the signature is valid
310 */
311int
312GNUNET_NAMESTORE_block_verify (const struct GNUNET_NAMESTORE_Block *block)
313{
314 GNUNET_break (0);
315 return GNUNET_SYSERR;
316}
317
318
319/**
320 * Decrypt block.
321 *
322 * @param block block to decrypt
323 * @param zone_key public key of the zone
324 * @param label the name for the records
325 * @param proc function to call with the result
326 * @param proc_cls closure for proc
327 * @param GNUNET_OK on success, GNUNET_SYSERR if the block was
328 * not well-formed
329 */
330int
331GNUNET_NAMESTORE_block_decrypt (const struct GNUNET_NAMESTORE_Block *block,
332 const struct GNUNET_CRYPTO_EccPublicKey *zone_key,
333 const char *label,
334 GNUNET_NAMESTORE_RecordMonitor proc,
335 void *proc_cls)
336{
337 GNUNET_break (0);
338 return GNUNET_SYSERR;
339}
340
341
342#if OLD
343/**
344 * Sign name and records
279 * 345 *
280 * @return the signature 346 * @param key the private key
347 * @param expire block expiration
348 * @param name the name
349 * @param rd record data
350 * @param rd_count number of records
351 * @param signature where to store the signature
281 */ 352 */
282struct GNUNET_CRYPTO_EccSignature * 353void
283GNUNET_NAMESTORE_create_signature (const struct GNUNET_CRYPTO_EccPrivateKey *key, 354GNUNET_NAMESTORE_create_signature (const struct GNUNET_CRYPTO_EccPrivateKey *key,
284 struct GNUNET_TIME_Absolute expire, 355 struct GNUNET_TIME_Absolute expire,
285 const char *name, 356 const char *name,
286 const struct GNUNET_NAMESTORE_RecordData *rd, 357 const struct GNUNET_NAMESTORE_RecordData *rd,
287 unsigned int rd_count) 358 unsigned int rd_count,
359 struct GNUNET_CRYPTO_EccSignature *signature)
360
288{ 361{
289 struct GNUNET_CRYPTO_EccSignature *sig; 362 struct GNUNET_CRYPTO_EccPrivateKey *dkey;
290 struct GNUNET_CRYPTO_EccSignaturePurpose *sig_purpose; 363 struct GNUNET_CRYPTO_EccSignaturePurpose *sig_purpose;
291 struct GNUNET_TIME_AbsoluteNBO expire_nbo; 364 struct GNUNET_TIME_AbsoluteNBO expire_nbo;
292 size_t rd_ser_len; 365 size_t rd_ser_len;
@@ -297,12 +370,7 @@ GNUNET_NAMESTORE_create_signature (const struct GNUNET_CRYPTO_EccPrivateKey *key
297 int res; 370 int res;
298 uint32_t sig_len; 371 uint32_t sig_len;
299 372
300 if (NULL == name) 373 dkey = GNUNET_CRYPTO_ecc_key_derive (key, name, "gns");
301 {
302 GNUNET_break (0);
303 return NULL;
304 }
305 sig = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignature));
306 name_len = strlen (name) + 1; 374 name_len = strlen (name) + 1;
307 expire_nbo = GNUNET_TIME_absolute_hton (expire); 375 expire_nbo = GNUNET_TIME_absolute_hton (expire);
308 rd_ser_len = GNUNET_NAMESTORE_records_get_size (rd_count, rd); 376 rd_ser_len = GNUNET_NAMESTORE_records_get_size (rd_count, rd);
@@ -321,17 +389,70 @@ GNUNET_NAMESTORE_create_signature (const struct GNUNET_CRYPTO_EccPrivateKey *key
321 memcpy (name_tmp, name, name_len); 389 memcpy (name_tmp, name, name_len);
322 rd_tmp = &name_tmp[name_len]; 390 rd_tmp = &name_tmp[name_len];
323 memcpy (rd_tmp, rd_ser, rd_ser_len); 391 memcpy (rd_tmp, rd_ser, rd_ser_len);
324 res = GNUNET_CRYPTO_ecc_sign (key, sig_purpose, sig); 392 GNUNET_assert (GNUNET_OK ==
393 GNUNET_CRYPTO_ecc_sign (dkey, sig_purpose, signature));
325 GNUNET_free (sig_purpose); 394 GNUNET_free (sig_purpose);
326 } 395 }
327 if (GNUNET_OK != res) 396 GNUNET_CRYPTO_ecc_key_free (dkey);
397}
398
399
400/**
401 * Check if a signature is valid. This API is used by the GNS Block
402 * to validate signatures received from the network.
403 *
404 * @param derived_key derived key of the zone and the label
405 * @param freshness time set for block expiration
406 * @param rd_count number of entries in 'rd' array
407 * @param rd array of records with data to store
408 * @param signature signature for all the records in the zone under the given name
409 * @return GNUNET_OK if the signature is valid
410 */
411int
412GNUNET_NAMESTORE_verify_signature (const struct GNUNET_CRYPTO_EccPublicKey *derived_key,
413 const struct GNUNET_TIME_Absolute freshness,
414 unsigned int rd_count,
415 const struct GNUNET_NAMESTORE_RecordData *rd,
416 const struct GNUNET_CRYPTO_EccSignature *signature)
417{
418 size_t rd_ser_len;
419 size_t name_len;
420 char *name_tmp;
421 char *rd_ser;
422 struct GNUNET_CRYPTO_EccSignaturePurpose *sig_purpose;
423 struct GNUNET_TIME_AbsoluteNBO *expire_tmp;
424 struct GNUNET_TIME_AbsoluteNBO expire_nbo = GNUNET_TIME_absolute_hton (freshness);
425 uint32_t sig_len;
426
427 GNUNET_assert (NULL != public_key);
428 GNUNET_assert (NULL != name);
429 GNUNET_assert (NULL != rd);
430 GNUNET_assert (NULL != signature);
431 name_len = strlen (name) + 1;
432 if (name_len > MAX_NAME_LEN)
328 { 433 {
329 GNUNET_break (0); 434 GNUNET_break (0);
330 GNUNET_free (sig); 435 return GNUNET_SYSERR;
331 return NULL; 436 }
437 rd_ser_len = GNUNET_NAMESTORE_records_get_size (rd_count, rd);
438 sig_len = sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + sizeof (struct GNUNET_TIME_AbsoluteNBO) + rd_ser_len + name_len;
439 {
440 char sig_buf[sig_len] GNUNET_ALIGN;
441
442 sig_purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose *) sig_buf;
443 sig_purpose->size = htonl (sig_len);
444 sig_purpose->purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
445 expire_tmp = (struct GNUNET_TIME_AbsoluteNBO *) &sig_purpose[1];
446 memcpy (expire_tmp, &expire_nbo, sizeof (struct GNUNET_TIME_AbsoluteNBO));
447 name_tmp = (char *) &expire_tmp[1];
448 memcpy (name_tmp, name, name_len);
449 rd_ser = &name_tmp[name_len];
450 GNUNET_assert (rd_ser_len ==
451 GNUNET_NAMESTORE_records_serialize (rd_count, rd, rd_ser_len, rd_ser));
452 return GNUNET_CRYPTO_ecc_verify (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN, sig_purpose, signature, public_key);
332 } 453 }
333 return sig;
334} 454}
455#endif
335 456
336 457
337/** 458/**
@@ -352,7 +473,6 @@ GNUNET_NAMESTORE_value_to_string (uint32_t type,
352 const struct vpn_data *vpn; 473 const struct vpn_data *vpn;
353 const struct srv_data *srv; 474 const struct srv_data *srv;
354 const struct tlsa_data *tlsa; 475 const struct tlsa_data *tlsa;
355 struct GNUNET_CRYPTO_ShortHashAsciiEncoded enc;
356 struct GNUNET_CRYPTO_HashAsciiEncoded s_peer; 476 struct GNUNET_CRYPTO_HashAsciiEncoded s_peer;
357 const char *cdata; 477 const char *cdata;
358 char* vpn_str; 478 char* vpn_str;
@@ -419,11 +539,9 @@ GNUNET_NAMESTORE_value_to_string (uint32_t type,
419 return NULL; 539 return NULL;
420 return GNUNET_strdup (tmp); 540 return GNUNET_strdup (tmp);
421 case GNUNET_NAMESTORE_TYPE_PKEY: 541 case GNUNET_NAMESTORE_TYPE_PKEY:
422 if (data_size != sizeof (struct GNUNET_CRYPTO_ShortHashCode)) 542 if (data_size != sizeof (struct GNUNET_CRYPTO_EccPublicKey))
423 return NULL; 543 return NULL;
424 GNUNET_CRYPTO_short_hash_to_enc (data, 544 return GNUNET_CRYPTO_ecc_public_key_to_string (data);
425 &enc);
426 return GNUNET_strdup ((const char*) enc.short_encoding);
427 case GNUNET_NAMESTORE_TYPE_PSEU: 545 case GNUNET_NAMESTORE_TYPE_PSEU:
428 return GNUNET_strndup (data, data_size); 546 return GNUNET_strndup (data, data_size);
429 case GNUNET_NAMESTORE_TYPE_LEHO: 547 case GNUNET_NAMESTORE_TYPE_LEHO:
@@ -505,7 +623,7 @@ GNUNET_NAMESTORE_string_to_value (uint32_t type,
505{ 623{
506 struct in_addr value_a; 624 struct in_addr value_a;
507 struct in6_addr value_aaaa; 625 struct in6_addr value_aaaa;
508 struct GNUNET_CRYPTO_ShortHashCode pkey; 626 struct GNUNET_CRYPTO_EccPublicKey pkey;
509 struct soa_data *soa; 627 struct soa_data *soa;
510 struct vpn_data *vpn; 628 struct vpn_data *vpn;
511 struct tlsa_data *tlsa; 629 struct tlsa_data *tlsa;
@@ -610,16 +728,16 @@ GNUNET_NAMESTORE_string_to_value (uint32_t type,
610 return GNUNET_OK; 728 return GNUNET_OK;
611 case GNUNET_NAMESTORE_TYPE_PKEY: 729 case GNUNET_NAMESTORE_TYPE_PKEY:
612 if (GNUNET_OK != 730 if (GNUNET_OK !=
613 GNUNET_CRYPTO_short_hash_from_string (s, &pkey)) 731 GNUNET_CRYPTO_ecc_public_key_from_string (s, strlen (s), &pkey))
614 { 732 {
615 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 733 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
616 _("Unable to parse PKEY record `%s'\n"), 734 _("Unable to parse PKEY record `%s'\n"),
617 s); 735 s);
618 return GNUNET_SYSERR; 736 return GNUNET_SYSERR;
619 } 737 }
620 *data = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_ShortHashCode)); 738 *data = GNUNET_new (struct GNUNET_CRYPTO_EccPublicKey);
621 memcpy (*data, &pkey, sizeof (pkey)); 739 memcpy (*data, &pkey, sizeof (pkey));
622 *data_size = sizeof (struct GNUNET_CRYPTO_ShortHashCode); 740 *data_size = sizeof (struct GNUNET_CRYPTO_EccPublicKey);
623 return GNUNET_OK; 741 return GNUNET_OK;
624 case GNUNET_NAMESTORE_TYPE_PSEU: 742 case GNUNET_NAMESTORE_TYPE_PSEU:
625 *data = GNUNET_strdup (s); 743 *data = GNUNET_strdup (s);
@@ -676,6 +794,10 @@ GNUNET_NAMESTORE_string_to_value (uint32_t type,
676} 794}
677 795
678 796
797/**
798 * Mapping of record type numbers to human-readable
799 * record type names.
800 */
679static struct { 801static struct {
680 const char *name; 802 const char *name;
681 uint32_t number; 803 uint32_t number;
@@ -734,6 +856,7 @@ GNUNET_NAMESTORE_number_to_typename (uint32_t type)
734 return name_map[i].name; 856 return name_map[i].name;
735} 857}
736 858
859
737/** 860/**
738 * Test if a given record is expired. 861 * Test if a given record is expired.
739 * 862 *
@@ -752,4 +875,42 @@ GNUNET_NAMESTORE_is_expired (const struct GNUNET_NAMESTORE_RecordData *rd)
752} 875}
753 876
754 877
878/**
879 * Calculate the DHT query for a given 'label' in a given zone.
880 *
881 * @param zone private key of the zone
882 * @param label label of the record
883 * @return query hash to use for the query
884 */
885void
886GNUNET_NAMESTORE_query_from_private_key (const struct GNUNET_CRYPTO_EccPrivateKey *zone,
887 const char *label,
888 struct GNUNET_HashCode *query)
889{
890 struct GNUNET_CRYPTO_EccPublicKey pub;
891
892 GNUNET_CRYPTO_ecc_key_get_public (zone, &pub);
893 GNUNET_NAMESTORE_query_from_public_key (&pub, label, query);
894}
895
896
897/**
898 * Calculate the DHT query for a given 'label' in a given zone.
899 *
900 * @param pub public key of the zone
901 * @param label label of the record
902 * @return query hash to use for the query
903 */
904void
905GNUNET_NAMESTORE_query_from_public_key (const struct GNUNET_CRYPTO_EccPublicKey *pub,
906 const char *label,
907 struct GNUNET_HashCode *query)
908{
909 struct GNUNET_CRYPTO_EccPublicKey pd;
910
911 GNUNET_CRYPTO_ecc_public_key_derive (pub, label, "gns", &pd);
912 GNUNET_CRYPTO_hash (&pd, sizeof (pd), query);
913}
914
915
755/* end of namestore_common.c */ 916/* end of namestore_common.c */
diff --git a/src/namestore/namestore_api_monitor.c b/src/namestore/namestore_api_monitor.c
index a6a014839..050d88ba5 100644
--- a/src/namestore/namestore_api_monitor.c
+++ b/src/namestore/namestore_api_monitor.c
@@ -73,12 +73,8 @@ struct GNUNET_NAMESTORE_ZoneMonitor
73 /** 73 /**
74 * Monitored zone. 74 * Monitored zone.
75 */ 75 */
76 struct GNUNET_CRYPTO_ShortHashCode zone; 76 struct GNUNET_CRYPTO_EccPrivateKey zone;
77 77
78 /**
79 * GNUNET_YES if we monitor all zones, GNUNET_NO if we only monitor 'zone'.
80 */
81 int all_zones;
82}; 78};
83 79
84 80
@@ -108,8 +104,7 @@ reconnect (struct GNUNET_NAMESTORE_ZoneMonitor *zm)
108 GNUNET_CLIENT_disconnect (zm->h); 104 GNUNET_CLIENT_disconnect (zm->h);
109 zm->monitor (zm->cls, 105 zm->monitor (zm->cls,
110 NULL, 106 NULL,
111 GNUNET_TIME_UNIT_ZERO_ABS, 107 NULL, 0, NULL);
112 NULL, 0, NULL, NULL);
113 GNUNET_assert (NULL != (zm->h = GNUNET_CLIENT_connect ("namestore", zm->cfg))); 108 GNUNET_assert (NULL != (zm->h = GNUNET_CLIENT_connect ("namestore", zm->cfg)));
114 zm->th = GNUNET_CLIENT_notify_transmit_ready (zm->h, 109 zm->th = GNUNET_CLIENT_notify_transmit_ready (zm->h,
115 sizeof (struct ZoneMonitorStartMessage), 110 sizeof (struct ZoneMonitorStartMessage),
@@ -132,7 +127,7 @@ handle_updates (void *cls,
132 const struct GNUNET_MessageHeader *msg) 127 const struct GNUNET_MessageHeader *msg)
133{ 128{
134 struct GNUNET_NAMESTORE_ZoneMonitor *zm = cls; 129 struct GNUNET_NAMESTORE_ZoneMonitor *zm = cls;
135 const struct LookupNameResponseMessage *lrm; 130 const struct RecordResultMessage *lrm;
136 size_t lrm_len; 131 size_t lrm_len;
137 size_t exp_lrm_len; 132 size_t exp_lrm_len;
138 size_t name_len; 133 size_t name_len;
@@ -140,7 +135,6 @@ handle_updates (void *cls,
140 unsigned rd_count; 135 unsigned rd_count;
141 const char *name_tmp; 136 const char *name_tmp;
142 const char *rd_ser_tmp; 137 const char *rd_ser_tmp;
143 struct GNUNET_TIME_Absolute expire;
144 138
145 if (NULL == msg) 139 if (NULL == msg)
146 { 140 {
@@ -158,20 +152,19 @@ handle_updates (void *cls,
158 zm->sync_cb (zm->cls); 152 zm->sync_cb (zm->cls);
159 return; 153 return;
160 } 154 }
161 if ( (ntohs (msg->size) < sizeof (struct LookupNameResponseMessage)) || 155 if ( (ntohs (msg->size) < sizeof (struct RecordResultMessage)) ||
162 (GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPONSE != ntohs (msg->type) ) ) 156 (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT != ntohs (msg->type) ) )
163 { 157 {
164 GNUNET_break (0); 158 GNUNET_break (0);
165 reconnect (zm); 159 reconnect (zm);
166 return; 160 return;
167 } 161 }
168 lrm = (const struct LookupNameResponseMessage *) msg; 162 lrm = (const struct RecordResultMessage *) msg;
169 lrm_len = ntohs (lrm->gns_header.header.size); 163 lrm_len = ntohs (lrm->gns_header.header.size);
170 rd_len = ntohs (lrm->rd_len); 164 rd_len = ntohs (lrm->rd_len);
171 rd_count = ntohs (lrm->rd_count); 165 rd_count = ntohs (lrm->rd_count);
172 name_len = ntohs (lrm->name_len); 166 name_len = ntohs (lrm->name_len);
173 expire = GNUNET_TIME_absolute_ntoh (lrm->expire); 167 exp_lrm_len = sizeof (struct RecordResultMessage) + name_len + rd_len;
174 exp_lrm_len = sizeof (struct LookupNameResponseMessage) + name_len + rd_len;
175 if (lrm_len != exp_lrm_len) 168 if (lrm_len != exp_lrm_len)
176 { 169 {
177 GNUNET_break (0); 170 GNUNET_break (0);
@@ -206,9 +199,9 @@ handle_updates (void *cls,
206 zm, 199 zm,
207 GNUNET_TIME_UNIT_FOREVER_REL); 200 GNUNET_TIME_UNIT_FOREVER_REL);
208 zm->monitor (zm->cls, 201 zm->monitor (zm->cls,
209 &lrm->public_key, expire, 202 &lrm->private_key,
210 name_tmp, 203 name_tmp,
211 rd_count, rd, NULL); 204 rd_count, rd);
212 } 205 }
213} 206}
214 207
@@ -239,7 +232,6 @@ transmit_monitor_message (void *cls,
239 sm.gns_header.header.size = htons (sizeof (struct ZoneMonitorStartMessage)); 232 sm.gns_header.header.size = htons (sizeof (struct ZoneMonitorStartMessage));
240 sm.gns_header.r_id = htonl (0); 233 sm.gns_header.r_id = htonl (0);
241 sm.zone = zm->zone; 234 sm.zone = zm->zone;
242 sm.all_zones = htonl (zm->all_zones);
243 memcpy (buf, &sm, sizeof (sm)); 235 memcpy (buf, &sm, sizeof (sm));
244 GNUNET_CLIENT_receive (zm->h, 236 GNUNET_CLIENT_receive (zm->h,
245 &handle_updates, 237 &handle_updates,
@@ -255,7 +247,7 @@ transmit_monitor_message (void *cls,
255 * a record changes. 247 * a record changes.
256 * 248 *
257 * @param cfg configuration to use to connect to namestore 249 * @param cfg configuration to use to connect to namestore
258 * @param zone zone to monitor, NULL for all zones 250 * @param zone zone to monitor
259 * @param monitor function to call on zone changes 251 * @param monitor function to call on zone changes
260 * @param sync_cb function called when we're in sync with the namestore 252 * @param sync_cb function called when we're in sync with the namestore
261 * @param cls closure for 'monitor' and 'sync_cb' 253 * @param cls closure for 'monitor' and 'sync_cb'
@@ -263,7 +255,7 @@ transmit_monitor_message (void *cls,
263 */ 255 */
264struct GNUNET_NAMESTORE_ZoneMonitor * 256struct GNUNET_NAMESTORE_ZoneMonitor *
265GNUNET_NAMESTORE_zone_monitor_start (const struct GNUNET_CONFIGURATION_Handle *cfg, 257GNUNET_NAMESTORE_zone_monitor_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
266 const struct GNUNET_CRYPTO_ShortHashCode *zone, 258 const struct GNUNET_CRYPTO_EccPrivateKey *zone,
267 GNUNET_NAMESTORE_RecordMonitor monitor, 259 GNUNET_NAMESTORE_RecordMonitor monitor,
268 GNUNET_NAMESTORE_RecordsSynchronizedCallback sync_cb, 260 GNUNET_NAMESTORE_RecordsSynchronizedCallback sync_cb,
269 void *cls) 261 void *cls)
@@ -276,10 +268,7 @@ GNUNET_NAMESTORE_zone_monitor_start (const struct GNUNET_CONFIGURATION_Handle *c
276 zm = GNUNET_new (struct GNUNET_NAMESTORE_ZoneMonitor); 268 zm = GNUNET_new (struct GNUNET_NAMESTORE_ZoneMonitor);
277 zm->cfg = cfg; 269 zm->cfg = cfg;
278 zm->h = client; 270 zm->h = client;
279 if (NULL == zone) 271 zm->zone = *zone;
280 zm->all_zones = GNUNET_YES;
281 else
282 zm->zone = *zone;
283 zm->monitor = monitor; 272 zm->monitor = monitor;
284 zm->sync_cb = sync_cb; 273 zm->sync_cb = sync_cb;
285 zm->cls = cls; 274 zm->cls = cls;
diff --git a/src/namestore/plugin_namestore_sqlite.c b/src/namestore/plugin_namestore_sqlite.c
index a7cc03434..3559dc7ce 100644
--- a/src/namestore/plugin_namestore_sqlite.c
+++ b/src/namestore/plugin_namestore_sqlite.c
@@ -31,14 +31,14 @@
31#include <sqlite3.h> 31#include <sqlite3.h>
32 32
33/** 33/**
34 * After how many ms "busy" should a DB operation fail for good? 34 * After how many ms "busy" should a DB operation fail for good? A
35 * A low value makes sure that we are more responsive to requests 35 * low value makes sure that we are more responsive to requests
36 * (especially PUTs). A high value guarantees a higher success 36 * (especially PUTs). A high value guarantees a higher success rate
37 * rate (SELECTs in iterate can take several seconds despite LIMIT=1). 37 * (SELECTs in iterate can take several seconds despite LIMIT=1).
38 * 38 *
39 * The default value of 1s should ensure that users do not experience 39 * The default value of 1s should ensure that users do not experience
40 * huge latencies while at the same time allowing operations to succeed 40 * huge latencies while at the same time allowing operations to
41 * with reasonable probability. 41 * succeed with reasonable probability.
42 */ 42 */
43#define BUSY_TIMEOUT_MS 1000 43#define BUSY_TIMEOUT_MS 1000
44 44
@@ -72,45 +72,40 @@ struct Plugin
72 sqlite3 *dbh; 72 sqlite3 *dbh;
73 73
74 /** 74 /**
75 * Precompiled SQL for put record 75 * Precompiled SQL for caching a block
76 */ 76 */
77 sqlite3_stmt *put_records; 77 sqlite3_stmt *cache_block;
78 78
79 /** 79 /**
80 * Precompiled SQL for remove record 80 * Precompiled SQL for looking up a block
81 */ 81 */
82 sqlite3_stmt *remove_records; 82 sqlite3_stmt *lookup_block;
83 83
84 /** 84 /**
85 * Precompiled SQL for iterate over all records. 85 * Precompiled SQL for removing expired blocks
86 */ 86 */
87 sqlite3_stmt *iterate_all; 87 sqlite3_stmt *expire_blocks;
88 88
89 /** 89 /**
90 * Precompiled SQL for iterate records with same name. 90 * Precompiled SQL to store records.
91 */ 91 */
92 sqlite3_stmt *iterate_by_name; 92 sqlite3_stmt *store_records;
93 93
94 /** 94 /**
95 * Precompiled SQL for iterate records with same zone. 95 * Precompiled SQL to deltete existing records.
96 */ 96 */
97 sqlite3_stmt *iterate_by_zone; 97 sqlite3_stmt *delete_records;
98 98
99 /** 99 /**
100 * Precompiled SQL for iterate records with same name and zone. 100 * Precompiled SQL for iterate records within a zone.
101 */ 101 */
102 sqlite3_stmt *iterate_records; 102 sqlite3_stmt *iterate_zone;
103 103
104 /** 104 /**
105 * Precompiled SQL to get the name for a given zone-value. 105 * Precompiled SQL to for reverse lookup based on PKEY.
106 */ 106 */
107 sqlite3_stmt *zone_to_name; 107 sqlite3_stmt *zone_to_name;
108 108
109 /**
110 * Precompiled SQL for delete zone
111 */
112 sqlite3_stmt *delete_zone;
113
114}; 109};
115 110
116 111
@@ -147,23 +142,17 @@ create_indices (sqlite3 * dbh)
147{ 142{
148 /* create indices */ 143 /* create indices */
149 if ( (SQLITE_OK != 144 if ( (SQLITE_OK !=
150 sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_zone_name_rv ON ns091records (zone_hash,record_name_hash,rvalue)", 145 sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_query_hash ON ns096blocks (query,expiration_time)",
151 NULL, NULL, NULL)) ||
152 (SQLITE_OK !=
153 sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_zone_delegation ON ns091records (zone_hash,zone_delegation)",
154 NULL, NULL, NULL)) ||
155 (SQLITE_OK !=
156 sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_zone_rv ON ns091records (zone_hash,rvalue)",
157 NULL, NULL, NULL)) || 146 NULL, NULL, NULL)) ||
158 (SQLITE_OK != 147 (SQLITE_OK !=
159 sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_zone ON ns091records (zone_hash)", 148 sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_block_expiration ON ns096blocks (expiration_time)",
160 NULL, NULL, NULL)) || 149 NULL, NULL, NULL)) ||
161 (SQLITE_OK != 150 (SQLITE_OK !=
162 sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_name_rv ON ns091records (record_name_hash,rvalue)", 151 sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_pkey_reverse ON ns096records (zone_private_key,pkey_hash)",
163 NULL, NULL, NULL)) || 152 NULL, NULL, NULL)) ||
164 (SQLITE_OK != 153 (SQLITE_OK !=
165 sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_rv ON ns091records (rvalue)", 154 sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS ir_pkey_iter ON ns096records (zone_private_key,rvalue)",
166 NULL, NULL, NULL)) ) 155 NULL, NULL, NULL)) )
167 LOG (GNUNET_ERROR_TYPE_ERROR, 156 LOG (GNUNET_ERROR_TYPE_ERROR,
168 "Failed to create indices: %s\n", sqlite3_errmsg (dbh)); 157 "Failed to create indices: %s\n", sqlite3_errmsg (dbh));
169} 158}
@@ -255,22 +244,38 @@ database_setup (struct Plugin *plugin)
255 /* Create tables */ 244 /* Create tables */
256 CHECK (SQLITE_OK == 245 CHECK (SQLITE_OK ==
257 sq_prepare (plugin->dbh, 246 sq_prepare (plugin->dbh,
258 "SELECT 1 FROM sqlite_master WHERE tbl_name = 'ns091records'", 247 "SELECT 1 FROM sqlite_master WHERE tbl_name = 'ns096blocks'",
248 &stmt));
249 if ((sqlite3_step (stmt) == SQLITE_DONE) &&
250 (sqlite3_exec
251 (plugin->dbh,
252 "CREATE TABLE ns096blocks ("
253 " query BLOB NOT NULL DEFAULT '',"
254 " block BLOB NOT NULL DEFAULT '',"
255 " expiration_time INT8 NOT NULL DEFAULT 0"
256 ")",
257 NULL, NULL, NULL) != SQLITE_OK))
258 {
259 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite3_exec");
260 sqlite3_finalize (stmt);
261 return GNUNET_SYSERR;
262 }
263 sqlite3_finalize (stmt);
264
265 CHECK (SQLITE_OK ==
266 sq_prepare (plugin->dbh,
267 "SELECT 1 FROM sqlite_master WHERE tbl_name = 'ns096records'",
259 &stmt)); 268 &stmt));
260 if ((sqlite3_step (stmt) == SQLITE_DONE) && 269 if ((sqlite3_step (stmt) == SQLITE_DONE) &&
261 (sqlite3_exec 270 (sqlite3_exec
262 (plugin->dbh, 271 (plugin->dbh,
263 "CREATE TABLE ns091records (" 272 "CREATE TABLE ns096records ("
264 " zone_key BLOB NOT NULL DEFAULT ''," 273 " zone_private_key BLOB NOT NULL DEFAULT '',"
265 " zone_delegation BLOB NOT NULL DEFAULT ''," 274 " pkey_hash BLOB,"
266 " zone_hash BLOB NOT NULL DEFAULT ''," 275 " rvalue INT8 NOT NULL DEFAULT '',"
267 " record_count INT NOT NULL DEFAULT 0," 276 " record_count INT NOT NULL DEFAULT 0,"
268 " record_data BLOB NOT NULL DEFAULT ''," 277 " record_data BLOB NOT NULL DEFAULT '',"
269 " block_expiration_time INT8 NOT NULL DEFAULT 0," 278 " label TEXT NOT NULL DEFAULT ''"
270 " signature BLOB NOT NULL DEFAULT '',"
271 " record_name TEXT NOT NULL DEFAULT '',"
272 " record_name_hash BLOB NOT NULL DEFAULT '',"
273 " rvalue INT8 NOT NULL DEFAULT ''"
274 ")", 279 ")",
275 NULL, NULL, NULL) != SQLITE_OK)) 280 NULL, NULL, NULL) != SQLITE_OK))
276 { 281 {
@@ -284,42 +289,35 @@ database_setup (struct Plugin *plugin)
284 289
285 if ((sq_prepare 290 if ((sq_prepare
286 (plugin->dbh, 291 (plugin->dbh,
287 "INSERT INTO ns091records (zone_key, record_name, record_count, record_data, block_expiration_time, signature, zone_delegation, zone_hash, record_name_hash, rvalue) VALUES " 292 "INSERT INTO ns096blocks (query,block,expiration_time) VALUES (?, ?, ?)",
288 "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", 293 &plugin->cache_block) != SQLITE_OK) ||
289 &plugin->put_records) != SQLITE_OK) ||
290 (sq_prepare 294 (sq_prepare
291 (plugin->dbh, 295 (plugin->dbh,
292 "DELETE FROM ns091records WHERE zone_hash=? AND record_name_hash=?", 296 "DELETE FROM ns096blocks WHERE expiration_time<?",
293 &plugin->remove_records) != SQLITE_OK) || 297 &plugin->expire_blocks) != SQLITE_OK) ||
294 (sq_prepare 298 (sq_prepare
295 (plugin->dbh, 299 (plugin->dbh,
296 "SELECT zone_key, record_name, record_count, record_data, block_expiration_time, signature" 300 "SELECT block FROM ns096blocks WHERE query=? ORDER BY expiration_time DESC LIMIT 1",
297 " FROM ns091records WHERE zone_hash=? AND record_name_hash=? ORDER BY rvalue LIMIT 1 OFFSET ?", 301 &plugin->lookup_block) != SQLITE_OK) ||
298 &plugin->iterate_records) != SQLITE_OK) ||
299 (sq_prepare 302 (sq_prepare
300 (plugin->dbh, 303 (plugin->dbh,
301 "SELECT zone_key, record_name, record_count, record_data, block_expiration_time, signature" 304 "INSERT INTO ns096records (zone_private_key, pkey_hash, rvalue, record_count, record_data, label)"
302 " FROM ns091records WHERE zone_hash=? ORDER BY rvalue LIMIT 1 OFFSET ?", 305 " VALUES (?, ?, ?, ?, ?, ?)",
303 &plugin->iterate_by_zone) != SQLITE_OK) || 306 &plugin->store_records) != SQLITE_OK) ||
304 (sq_prepare 307 (sq_prepare
305 (plugin->dbh, 308 (plugin->dbh,
306 "SELECT zone_key, record_name, record_count, record_data, block_expiration_time, signature" 309 "DELETE FROM ns096records WHERE zone_private_key=? AND label=?",
307 " FROM ns091records WHERE record_name_hash=? ORDER BY rvalue LIMIT 1 OFFSET ?", 310 &plugin->delete_records) != SQLITE_OK) ||
308 &plugin->iterate_by_name) != SQLITE_OK) ||
309 (sq_prepare
310 (plugin->dbh,
311 "SELECT zone_key, record_name, record_count, record_data, block_expiration_time, signature"
312 " FROM ns091records ORDER BY rvalue LIMIT 1 OFFSET ?",
313 &plugin->iterate_all) != SQLITE_OK) ||
314 (sq_prepare 311 (sq_prepare
315 (plugin->dbh, 312 (plugin->dbh,
316 "SELECT zone_key, record_name, record_count, record_data, block_expiration_time, signature" 313 "SELECT record_count,record_data,label"
317 " FROM ns091records WHERE zone_hash=? AND zone_delegation=?", 314 " FROM ns096records WHERE zone_private_key=? AND pkey_hash=?",
318 &plugin->zone_to_name) != SQLITE_OK) || 315 &plugin->zone_to_name) != SQLITE_OK) ||
319 (sq_prepare 316 (sq_prepare
320 (plugin->dbh, 317 (plugin->dbh,
321 "DELETE FROM ns091records WHERE zone_hash=?", 318 "SELECT record_count,record_data,label"
322 &plugin->delete_zone) != SQLITE_OK) ) 319 " FROM ns096records WHERE zone_private_key=? ORDER BY rvalue LIMIT 1 OFFSET ?",
320 &plugin->iterate_zone) != SQLITE_OK) )
323 { 321 {
324 LOG_SQLITE (plugin,GNUNET_ERROR_TYPE_ERROR, "precompiling"); 322 LOG_SQLITE (plugin,GNUNET_ERROR_TYPE_ERROR, "precompiling");
325 return GNUNET_SYSERR; 323 return GNUNET_SYSERR;
@@ -339,22 +337,20 @@ database_shutdown (struct Plugin *plugin)
339 int result; 337 int result;
340 sqlite3_stmt *stmt; 338 sqlite3_stmt *stmt;
341 339
342 if (NULL != plugin->put_records) 340 if (NULL != plugin->cache_block)
343 sqlite3_finalize (plugin->put_records); 341 sqlite3_finalize (plugin->cache_block);
344 if (NULL != plugin->remove_records) 342 if (NULL != plugin->expire_blocks)
345 sqlite3_finalize (plugin->remove_records); 343 sqlite3_finalize (plugin->expire_blocks);
346 if (NULL != plugin->iterate_records) 344 if (NULL != plugin->lookup_block)
347 sqlite3_finalize (plugin->iterate_records); 345 sqlite3_finalize (plugin->lookup_block);
348 if (NULL != plugin->iterate_by_zone) 346 if (NULL != plugin->store_records)
349 sqlite3_finalize (plugin->iterate_by_zone); 347 sqlite3_finalize (plugin->store_records);
350 if (NULL != plugin->iterate_by_name) 348 if (NULL != plugin->delete_records)
351 sqlite3_finalize (plugin->iterate_by_name); 349 sqlite3_finalize (plugin->delete_records);
352 if (NULL != plugin->iterate_all) 350 if (NULL != plugin->iterate_zone)
353 sqlite3_finalize (plugin->iterate_all); 351 sqlite3_finalize (plugin->iterate_zone);
354 if (NULL != plugin->zone_to_name) 352 if (NULL != plugin->zone_to_name)
355 sqlite3_finalize (plugin->zone_to_name); 353 sqlite3_finalize (plugin->zone_to_name);
356 if (NULL != plugin->delete_zone)
357 sqlite3_finalize (plugin->delete_zone);
358 result = sqlite3_close (plugin->dbh); 354 result = sqlite3_close (plugin->dbh);
359 if (result == SQLITE_BUSY) 355 if (result == SQLITE_BUSY)
360 { 356 {
@@ -381,55 +377,179 @@ database_shutdown (struct Plugin *plugin)
381 377
382 378
383/** 379/**
384 * Removes any existing record in the given zone with the same name. 380 * Removes any expired block.
385 * 381 *
386 * @param cls closure (internal context for the plugin) 382 * @param plugin the plugin
387 * @param zone hash of the public key of the zone
388 * @param name name to remove (at most 255 characters long)
389 * @return GNUNET_OK on success
390 */ 383 */
391static int 384static void
392namestore_sqlite_remove_records (void *cls, 385namestore_sqlite_expire_blocks (struct Plugin *plugin)
393 const struct GNUNET_CRYPTO_ShortHashCode *zone,
394 const char *name)
395{ 386{
396 struct Plugin *plugin = cls; 387 struct GNUNET_TIME_Absolute now;
397 struct GNUNET_CRYPTO_ShortHashCode nh;
398 size_t name_len;
399 int n; 388 int n;
400 389
401 name_len = strlen (name); 390 now = GNUNET_TIME_absolute_get ();
402 GNUNET_CRYPTO_short_hash (name, name_len, &nh); 391 if (SQLITE_OK != sqlite3_bind_int64 (plugin->expire_blocks,
403 392 1, now.abs_value_us))
404 if ((SQLITE_OK != sqlite3_bind_blob (plugin->remove_records, 1, zone, sizeof (struct GNUNET_CRYPTO_ShortHashCode), SQLITE_STATIC)) ||
405 (SQLITE_OK != sqlite3_bind_blob (plugin->remove_records, 2, &nh, sizeof (struct GNUNET_CRYPTO_ShortHashCode), SQLITE_STATIC)))
406 { 393 {
407 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 394 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
408 "sqlite3_bind_XXXX"); 395 "sqlite3_bind_XXXX");
409 if (SQLITE_OK != sqlite3_reset (plugin->remove_records)) 396 if (SQLITE_OK != sqlite3_reset (plugin->expire_blocks))
410 LOG_SQLITE (plugin, 397 LOG_SQLITE (plugin,
411 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 398 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
412 "sqlite3_reset"); 399 "sqlite3_reset");
413 return GNUNET_SYSERR; 400 return;
414 } 401 }
415 n = sqlite3_step (plugin->remove_records); 402 n = sqlite3_step (plugin->expire_blocks);
416 if (SQLITE_OK != sqlite3_reset (plugin->remove_records)) 403 if (SQLITE_OK != sqlite3_reset (plugin->expire_blocks))
417 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 404 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
418 "sqlite3_reset"); 405 "sqlite3_reset");
419 switch (n) 406 switch (n)
420 { 407 {
421 case SQLITE_DONE: 408 case SQLITE_DONE:
422 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Record removed\n"); 409 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Records expired\n");
423 return GNUNET_OK; 410 return;
424 case SQLITE_BUSY: 411 case SQLITE_BUSY:
425 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, 412 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK,
426 "sqlite3_step"); 413 "sqlite3_step");
427 return GNUNET_NO; 414 return;
428 default: 415 default:
429 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 416 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
430 "sqlite3_step"); 417 "sqlite3_step");
418 return;
419 }
420}
421
422
423/**
424 * Cache a block in the datastore.
425 *
426 * @param cls closure (internal context for the plugin)
427 * @param block block to cache
428 * @return GNUNET_OK on success, else GNUNET_SYSERR
429 */
430static int
431namestore_sqlite_cache_block (void *cls,
432 const struct GNUNET_NAMESTORE_Block *block)
433{
434 struct Plugin *plugin = cls;
435 struct GNUNET_HashCode query;
436 struct GNUNET_TIME_Absolute expiration;
437 size_t block_size;
438 int n;
439
440 namestore_sqlite_expire_blocks (plugin);
441 GNUNET_CRYPTO_hash (&block->derived_key,
442 sizeof (struct GNUNET_CRYPTO_EccPublicKey),
443 &query);
444 expiration = GNUNET_TIME_absolute_ntoh (block->expiration_time);
445 block_size = ntohl (block->purpose.size) +
446 sizeof (struct GNUNET_CRYPTO_EccPublicKey) +
447 sizeof (struct GNUNET_CRYPTO_EccSignature);
448 if (block_size > 64 * 65536)
449 {
450 GNUNET_break (0);
451 return GNUNET_SYSERR;
452 }
453 if ((SQLITE_OK != sqlite3_bind_blob (plugin->cache_block, 1, &query, sizeof (struct GNUNET_HashCode), SQLITE_STATIC)) ||
454 (SQLITE_OK != sqlite3_bind_blob (plugin->cache_block, 2, block, block_size, SQLITE_STATIC)) ||
455 (SQLITE_OK != sqlite3_bind_int64 (plugin->cache_block, 3, expiration.abs_value_us)))
456 {
457 LOG_SQLITE (plugin,
458 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
459 "sqlite3_bind_XXXX");
460 if (SQLITE_OK != sqlite3_reset (plugin->cache_block))
461 LOG_SQLITE (plugin,
462 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
463 "sqlite3_reset");
464 return GNUNET_SYSERR;
465
466 }
467 n = sqlite3_step (plugin->cache_block);
468 if (SQLITE_OK != sqlite3_reset (plugin->cache_block))
469 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
470 "sqlite3_reset");
471 switch (n)
472 {
473 case SQLITE_DONE:
474 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Record stored\n");
475 return GNUNET_OK;
476 case SQLITE_BUSY:
477 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK,
478 "sqlite3_step");
479 return GNUNET_NO;
480 default:
481 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
482 "sqlite3_step");
483 return GNUNET_SYSERR;
484 }
485}
486
487
488/**
489 * Get the block for a particular zone and label in the
490 * datastore. Will return at most one result to the iterator.
491 *
492 * @param cls closure (internal context for the plugin)
493 * @param query hash of public key derived from the zone and the label
494 * @param iter function to call with the result
495 * @param iter_cls closure for iter
496 * @return GNUNET_OK on success, GNUNET_NO if there were no results, GNUNET_SYSERR on error
497 * 'iter' will have been called unless the return value is 'GNUNET_SYSERR'
498 */
499static int
500namestore_sqlite_lookup_block (void *cls,
501 const struct GNUNET_HashCode *query,
502 GNUNET_NAMESTORE_BlockCallback iter, void *iter_cls)
503{
504 struct Plugin *plugin = cls;
505 int ret;
506 int sret;
507 size_t block_size;
508 const struct GNUNET_NAMESTORE_Block *block;
509
510 if (SQLITE_OK != sqlite3_bind_blob (plugin->lookup_block, 1,
511 query, sizeof (struct GNUNET_HashCode),
512 SQLITE_STATIC))
513 {
514 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
515 "sqlite3_bind_XXXX");
516 if (SQLITE_OK != sqlite3_reset (plugin->lookup_block))
517 LOG_SQLITE (plugin,
518 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
519 "sqlite3_reset");
431 return GNUNET_SYSERR; 520 return GNUNET_SYSERR;
521 }
522
523 ret = GNUNET_NO;
524 if (SQLITE_ROW == (sret = sqlite3_step (plugin->lookup_block)))
525 {
526 ret = GNUNET_YES;
527 block = sqlite3_column_blob (plugin->lookup_block, 0);
528 block_size = sqlite3_column_bytes (plugin->lookup_block, 0);
529 if ( (block_size < sizeof (struct GNUNET_NAMESTORE_Block)) ||
530 (ntohl (block->purpose.size) +
531 sizeof (struct GNUNET_CRYPTO_EccPublicKey) +
532 sizeof (struct GNUNET_CRYPTO_EccSignature) != block_size) )
533 {
534 GNUNET_break (0);
535 ret = GNUNET_SYSERR;
536 }
537 else
538 {
539 iter (iter_cls, block);
540 }
541 }
542 else
543 {
544 if (SQLITE_DONE != sret)
545 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite_step");
546 iter (iter_cls, NULL);
432 } 547 }
548 if (SQLITE_OK != sqlite3_reset (plugin->lookup_block))
549 LOG_SQLITE (plugin,
550 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
551 "sqlite3_reset");
552 return ret;
433} 553}
434 554
435 555
@@ -438,47 +558,34 @@ namestore_sqlite_remove_records (void *cls,
438 * same zone with the same name. 558 * same zone with the same name.
439 * 559 *
440 * @param cls closure (internal context for the plugin) 560 * @param cls closure (internal context for the plugin)
441 * @param zone_key public key of the zone 561 * @param zone_key private key of the zone
442 * @param expire when does the corresponding block in the DHT expire (until 562 * @param label name that is being mapped (at most 255 characters long)
443 * when should we never do a DHT lookup for the same name again)?
444 * @param name name that is being mapped (at most 255 characters long)
445 * @param rd_count number of entries in 'rd' array 563 * @param rd_count number of entries in 'rd' array
446 * @param rd array of records with data to store 564 * @param rd array of records with data to store
447 * @param signature signature of the record block, NULL if signature is unavailable (i.e.
448 * because the user queried for a particular record type only)
449 * @return GNUNET_OK on success, else GNUNET_SYSERR 565 * @return GNUNET_OK on success, else GNUNET_SYSERR
450 */ 566 */
451static int 567static int
452namestore_sqlite_put_records (void *cls, 568namestore_sqlite_store_records (void *cls,
453 const struct GNUNET_CRYPTO_EccPublicKey *zone_key, 569 const struct GNUNET_CRYPTO_EccPrivateKey *zone_key,
454 struct GNUNET_TIME_Absolute expire, 570 const char *label,
455 const char *name, 571 unsigned int rd_count,
456 unsigned int rd_count, 572 const struct GNUNET_NAMESTORE_RecordData *rd)
457 const struct GNUNET_NAMESTORE_RecordData *rd,
458 const struct GNUNET_CRYPTO_EccSignature *signature)
459{ 573{
460 struct Plugin *plugin = cls; 574 struct Plugin *plugin = cls;
461 int n; 575 int n;
462 struct GNUNET_CRYPTO_ShortHashCode zone; 576 struct GNUNET_HashCode pkey_hash;
463 struct GNUNET_CRYPTO_ShortHashCode zone_delegation;
464 struct GNUNET_CRYPTO_ShortHashCode nh;
465 size_t name_len;
466 uint64_t rvalue; 577 uint64_t rvalue;
467 size_t data_size; 578 size_t data_size;
468 unsigned int i; 579 unsigned int i;
469 580
470 GNUNET_CRYPTO_short_hash (zone_key, sizeof (struct GNUNET_CRYPTO_EccPublicKey), &zone); 581 memset (&pkey_hash, 0, sizeof (pkey_hash));
471 (void) namestore_sqlite_remove_records (plugin, &zone, name);
472 name_len = strlen (name);
473 GNUNET_CRYPTO_short_hash (name, name_len, &nh);
474 memset (&zone_delegation, 0, sizeof (zone_delegation));
475 for (i=0;i<rd_count;i++) 582 for (i=0;i<rd_count;i++)
476 if (rd[i].record_type == GNUNET_NAMESTORE_TYPE_PKEY) 583 if (GNUNET_NAMESTORE_TYPE_PKEY == rd[i].record_type)
477 { 584 {
478 GNUNET_assert (sizeof (struct GNUNET_CRYPTO_ShortHashCode) == rd[i].data_size); 585 GNUNET_break (sizeof (struct GNUNET_CRYPTO_EccPublicKey) == rd[i].data_size);
479 memcpy (&zone_delegation, 586 GNUNET_CRYPTO_hash (rd[i].data,
480 rd[i].data, 587 rd[i].data_size,
481 sizeof (struct GNUNET_CRYPTO_ShortHashCode)); 588 &pkey_hash);
482 break; 589 break;
483 } 590 }
484 rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX); 591 rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX);
@@ -497,31 +604,52 @@ namestore_sqlite_put_records (void *cls,
497 GNUNET_break (0); 604 GNUNET_break (0);
498 return GNUNET_SYSERR; 605 return GNUNET_SYSERR;
499 } 606 }
500 if ((SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 1, zone_key, sizeof (struct GNUNET_CRYPTO_EccPublicKey), SQLITE_STATIC)) || 607
501 (SQLITE_OK != sqlite3_bind_text (plugin->put_records, 2, name, -1, SQLITE_STATIC)) || 608 /* First delete 'old' records */
502 (SQLITE_OK != sqlite3_bind_int (plugin->put_records, 3, rd_count)) || 609 if ((SQLITE_OK != sqlite3_bind_blob (plugin->delete_records, 1,
503 (SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 4, data, data_size, SQLITE_STATIC)) || 610 zone_key, sizeof (struct GNUNET_CRYPTO_EccPrivateKey), SQLITE_STATIC)) ||
504 (SQLITE_OK != sqlite3_bind_int64 (plugin->put_records, 5, expire.abs_value_us)) || 611 (SQLITE_OK != sqlite3_bind_text (plugin->delete_records, 2, label, -1, SQLITE_STATIC)))
505 (SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 6, signature, sizeof (struct GNUNET_CRYPTO_EccSignature), SQLITE_STATIC)) ||
506 (SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 7, &zone_delegation, sizeof (struct GNUNET_CRYPTO_ShortHashCode), SQLITE_STATIC)) ||
507 (SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 8, &zone, sizeof (struct GNUNET_CRYPTO_ShortHashCode), SQLITE_STATIC)) ||
508 (SQLITE_OK != sqlite3_bind_blob (plugin->put_records, 9, &nh, sizeof (struct GNUNET_CRYPTO_ShortHashCode), SQLITE_STATIC)) ||
509 (SQLITE_OK != sqlite3_bind_int64 (plugin->put_records, 10, rvalue)) )
510 { 612 {
511 LOG_SQLITE (plugin, 613 LOG_SQLITE (plugin,
512 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 614 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
513 "sqlite3_bind_XXXX"); 615 "sqlite3_bind_XXXX");
514 if (SQLITE_OK != sqlite3_reset (plugin->put_records)) 616 if (SQLITE_OK != sqlite3_reset (plugin->delete_records))
515 LOG_SQLITE (plugin, 617 LOG_SQLITE (plugin,
516 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 618 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
517 "sqlite3_reset"); 619 "sqlite3_reset");
518 return GNUNET_SYSERR; 620 return GNUNET_SYSERR;
519 621
520 } 622 }
521 n = sqlite3_step (plugin->put_records); 623 n = sqlite3_step (plugin->delete_records);
522 if (SQLITE_OK != sqlite3_reset (plugin->put_records)) 624 if (SQLITE_OK != sqlite3_reset (plugin->delete_records))
523 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 625 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
524 "sqlite3_reset"); 626 "sqlite3_reset");
627
628 if (0 != rd_count)
629 {
630 if ((SQLITE_OK != sqlite3_bind_blob (plugin->store_records, 1,
631 zone_key, sizeof (struct GNUNET_CRYPTO_EccPrivateKey), SQLITE_STATIC)) ||
632 (SQLITE_OK != sqlite3_bind_blob (plugin->store_records, 2,
633 &pkey_hash, sizeof (struct GNUNET_HashCode), SQLITE_STATIC)) ||
634 (SQLITE_OK != sqlite3_bind_int64 (plugin->store_records, 3, rvalue)) ||
635 (SQLITE_OK != sqlite3_bind_int (plugin->store_records, 4, rd_count)) ||
636 (SQLITE_OK != sqlite3_bind_blob (plugin->store_records, 5, data, data_size, SQLITE_STATIC)) ||
637 (SQLITE_OK != sqlite3_bind_text (plugin->store_records, 6, label, -1, SQLITE_STATIC)))
638 {
639 LOG_SQLITE (plugin,
640 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
641 "sqlite3_bind_XXXX");
642 if (SQLITE_OK != sqlite3_reset (plugin->store_records))
643 LOG_SQLITE (plugin,
644 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
645 "sqlite3_reset");
646 return GNUNET_SYSERR;
647 }
648 n = sqlite3_step (plugin->store_records);
649 if (SQLITE_OK != sqlite3_reset (plugin->store_records))
650 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
651 "sqlite3_reset");
652 }
525 } 653 }
526 switch (n) 654 switch (n)
527 { 655 {
@@ -547,6 +675,7 @@ namestore_sqlite_put_records (void *cls,
547 * 675 *
548 * @param plugin plugin context 676 * @param plugin plugin context
549 * @param stmt to run (and then clean up) 677 * @param stmt to run (and then clean up)
678 * @param zone_key private key of the zone
550 * @param iter iterator to call with the result 679 * @param iter iterator to call with the result
551 * @param iter_cls closure for 'iter' 680 * @param iter_cls closure for 'iter'
552 * @return GNUNET_OK on success, GNUNET_NO if there were no results, GNUNET_SYSERR on error 681 * @return GNUNET_OK on success, GNUNET_NO if there were no results, GNUNET_SYSERR on error
@@ -554,37 +683,26 @@ namestore_sqlite_put_records (void *cls,
554static int 683static int
555get_record_and_call_iterator (struct Plugin *plugin, 684get_record_and_call_iterator (struct Plugin *plugin,
556 sqlite3_stmt *stmt, 685 sqlite3_stmt *stmt,
686 const struct GNUNET_CRYPTO_EccPrivateKey *zone_key,
557 GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls) 687 GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
558{ 688{
559 int ret;
560 int sret;
561 unsigned int record_count; 689 unsigned int record_count;
562 size_t data_size; 690 size_t data_size;
563 const struct GNUNET_CRYPTO_EccPublicKey *zone_key;
564 const struct GNUNET_CRYPTO_EccSignature *sig;
565 struct GNUNET_TIME_Absolute expiration;
566 const char *data; 691 const char *data;
567 const char *name; 692 const char *label;
693 int ret;
694 int sret;
568 695
569 ret = GNUNET_NO; 696 ret = GNUNET_NO;
570 if (SQLITE_ROW == (sret = sqlite3_step (stmt))) 697 if (SQLITE_ROW == (sret = sqlite3_step (stmt)))
571 { 698 {
572 ret = GNUNET_YES; 699 ret = GNUNET_YES;
573 zone_key = sqlite3_column_blob (stmt, 0); 700 record_count = sqlite3_column_int (stmt, 0);
574 name = (const char*) sqlite3_column_text (stmt, 1); 701 data_size = sqlite3_column_bytes (stmt, 1);
575 record_count = sqlite3_column_int (stmt, 2); 702 data = sqlite3_column_blob (stmt, 1);
576 data_size = sqlite3_column_bytes (stmt, 3); 703 label = (const char*) sqlite3_column_text (stmt, 2);
577 data = sqlite3_column_blob (stmt, 3); 704
578 expiration.abs_value_us = (uint64_t) sqlite3_column_int64 (stmt, 4); 705 if (record_count > 64 * 1024)
579 sig = sqlite3_column_blob (stmt, 5);
580
581 if ( (sizeof (struct GNUNET_CRYPTO_EccPublicKey) != sqlite3_column_bytes (stmt, 0)) ||
582 (sizeof (struct GNUNET_CRYPTO_EccSignature) != sqlite3_column_bytes (stmt, 5)) )
583 {
584 GNUNET_break (0);
585 ret = GNUNET_SYSERR;
586 }
587 else if (record_count > 64 * 1024)
588 { 706 {
589 /* sanity check, don't stack allocate far too much just 707 /* sanity check, don't stack allocate far too much just
590 because database might contain a large value here */ 708 because database might contain a large value here */
@@ -604,8 +722,8 @@ get_record_and_call_iterator (struct Plugin *plugin,
604 } 722 }
605 else 723 else
606 { 724 {
607 iter (iter_cls, zone_key, expiration, name, 725 iter (iter_cls, zone_key, label,
608 record_count, rd, sig); 726 record_count, rd);
609 } 727 }
610 } 728 }
611 } 729 }
@@ -613,7 +731,7 @@ get_record_and_call_iterator (struct Plugin *plugin,
613 { 731 {
614 if (SQLITE_DONE != sret) 732 if (SQLITE_DONE != sret)
615 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite_step"); 733 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite_step");
616 iter (iter_cls, NULL, GNUNET_TIME_UNIT_ZERO_ABS, NULL, 0, NULL, NULL); 734 iter (iter_cls, NULL, NULL, 0, NULL);
617 } 735 }
618 if (SQLITE_OK != sqlite3_reset (stmt)) 736 if (SQLITE_OK != sqlite3_reset (stmt))
619 LOG_SQLITE (plugin, 737 LOG_SQLITE (plugin,
@@ -621,15 +739,14 @@ get_record_and_call_iterator (struct Plugin *plugin,
621 "sqlite3_reset"); 739 "sqlite3_reset");
622 return ret; 740 return ret;
623} 741}
624 742
625 743
626/** 744/**
627 * Iterate over the results for a particular key and zone in the 745 * Iterate over the results for a particular key and zone in the
628 * datastore. Will return at most one result to the iterator. 746 * datastore. Will return at most one result to the iterator.
629 * 747 *
630 * @param cls closure (internal context for the plugin) 748 * @param cls closure (internal context for the plugin)
631 * @param zone hash of public key of the zone, NULL to iterate over all zones 749 * @param zone hash of public key of the zone, NULL to iterate over all zones
632 * @param name name as string, NULL to iterate over all records of the zone
633 * @param offset offset in the list of all matching records 750 * @param offset offset in the list of all matching records
634 * @param iter function to call with the result 751 * @param iter function to call with the result
635 * @param iter_cls closure for iter 752 * @param iter_cls closure for iter
@@ -637,55 +754,21 @@ get_record_and_call_iterator (struct Plugin *plugin,
637 */ 754 */
638static int 755static int
639namestore_sqlite_iterate_records (void *cls, 756namestore_sqlite_iterate_records (void *cls,
640 const struct GNUNET_CRYPTO_ShortHashCode *zone, 757 const struct GNUNET_CRYPTO_EccPrivateKey *zone,
641 const char *name,
642 uint64_t offset, 758 uint64_t offset,
643 GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls) 759 GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
644{ 760{
645 struct Plugin *plugin = cls; 761 struct Plugin *plugin = cls;
646 sqlite3_stmt *stmt; 762 sqlite3_stmt *stmt;
647 struct GNUNET_CRYPTO_ShortHashCode name_hase;
648 unsigned int boff;
649 763
650 if (NULL == zone) 764 stmt = plugin->iterate_zone;
651 if (NULL == name)
652 stmt = plugin->iterate_all;
653 else
654 {
655 GNUNET_CRYPTO_short_hash (name, strlen(name), &name_hase);
656 stmt = plugin->iterate_by_name;
657 }
658 else
659 if (NULL == name)
660 stmt = plugin->iterate_by_zone;
661 else
662 {
663 GNUNET_CRYPTO_short_hash (name, strlen(name), &name_hase);
664 stmt = plugin->iterate_records;
665 }
666 765
667 boff = 0; 766 if ( (SQLITE_OK != sqlite3_bind_blob (stmt, 1,
668 if ( (NULL != zone) && 767 zone, sizeof (struct GNUNET_CRYPTO_EccPrivateKey),
669 (SQLITE_OK != sqlite3_bind_blob (stmt, ++boff, 768 SQLITE_STATIC)) ||
670 zone, sizeof (struct GNUNET_CRYPTO_ShortHashCode), 769 (SQLITE_OK != sqlite3_bind_int64 (stmt, 2,
671 SQLITE_STATIC)) ) 770 offset)) )
672 {
673 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
674 "sqlite3_bind_XXXX");
675 if (SQLITE_OK != sqlite3_reset (stmt))
676 LOG_SQLITE (plugin,
677 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
678 "sqlite3_reset");
679 return GNUNET_SYSERR;
680 }
681 if ( (NULL != name) &&
682 (SQLITE_OK != sqlite3_bind_blob (stmt, ++boff,
683 &name_hase, sizeof (struct GNUNET_CRYPTO_ShortHashCode),
684 SQLITE_STATIC)) )
685 { 771 {
686 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
687 "ITERATE NAME HASH: `%8s'",
688 GNUNET_NAMESTORE_short_h2s(&name_hase));
689 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 772 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
690 "sqlite3_bind_XXXX"); 773 "sqlite3_bind_XXXX");
691 if (SQLITE_OK != sqlite3_reset (stmt)) 774 if (SQLITE_OK != sqlite3_reset (stmt))
@@ -694,20 +777,7 @@ namestore_sqlite_iterate_records (void *cls,
694 "sqlite3_reset"); 777 "sqlite3_reset");
695 return GNUNET_SYSERR; 778 return GNUNET_SYSERR;
696 } 779 }
697 780 return get_record_and_call_iterator (plugin, stmt, zone, iter, iter_cls);
698 if (SQLITE_OK != sqlite3_bind_int64 (stmt, ++boff,
699 offset))
700 {
701 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
702 "sqlite3_bind_XXXX");
703 if (SQLITE_OK != sqlite3_reset (stmt))
704 LOG_SQLITE (plugin,
705 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
706 "sqlite3_reset");
707 return GNUNET_SYSERR;
708 }
709
710 return get_record_and_call_iterator (plugin, stmt, iter, iter_cls);
711} 781}
712 782
713 783
@@ -716,16 +786,16 @@ namestore_sqlite_iterate_records (void *cls,
716 * Returns at most one result to the iterator. 786 * Returns at most one result to the iterator.
717 * 787 *
718 * @param cls closure (internal context for the plugin) 788 * @param cls closure (internal context for the plugin)
719 * @param zone hash of public key of the zone to look up in, never NULL 789 * @param zone private key of the zone to look up in, never NULL
720 * @param value_zone hash of the public key of the target zone (value), never NULL 790 * @param value_zone public key of the target zone (value), never NULL
721 * @param iter function to call with the result 791 * @param iter function to call with the result
722 * @param iter_cls closure for iter 792 * @param iter_cls closure for iter
723 * @return GNUNET_OK on success, GNUNET_NO if there were no results, GNUNET_SYSERR on error 793 * @return GNUNET_OK on success, GNUNET_NO if there were no results, GNUNET_SYSERR on error
724 */ 794 */
725static int 795static int
726namestore_sqlite_zone_to_name (void *cls, 796namestore_sqlite_zone_to_name (void *cls,
727 const struct GNUNET_CRYPTO_ShortHashCode *zone, 797 const struct GNUNET_CRYPTO_EccPrivateKey *zone,
728 const struct GNUNET_CRYPTO_ShortHashCode *value_zone, 798 const struct GNUNET_CRYPTO_EccPublicKey *value_zone,
729 GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls) 799 GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
730{ 800{
731 struct Plugin *plugin = cls; 801 struct Plugin *plugin = cls;
@@ -733,10 +803,10 @@ namestore_sqlite_zone_to_name (void *cls,
733 803
734 stmt = plugin->zone_to_name; 804 stmt = plugin->zone_to_name;
735 if ( (SQLITE_OK != sqlite3_bind_blob (stmt, 1, 805 if ( (SQLITE_OK != sqlite3_bind_blob (stmt, 1,
736 zone, sizeof (struct GNUNET_CRYPTO_ShortHashCode), 806 zone, sizeof (struct GNUNET_CRYPTO_EccPrivateKey),
737 SQLITE_STATIC)) || 807 SQLITE_STATIC)) ||
738 (SQLITE_OK != sqlite3_bind_blob (stmt, 2, 808 (SQLITE_OK != sqlite3_bind_blob (stmt, 2,
739 value_zone, sizeof (struct GNUNET_CRYPTO_ShortHashCode), 809 value_zone, sizeof (struct GNUNET_CRYPTO_EccPublicKey),
740 SQLITE_STATIC)) ) 810 SQLITE_STATIC)) )
741 { 811 {
742 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 812 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
@@ -747,52 +817,7 @@ namestore_sqlite_zone_to_name (void *cls,
747 "sqlite3_reset"); 817 "sqlite3_reset");
748 return GNUNET_SYSERR; 818 return GNUNET_SYSERR;
749 } 819 }
750 return get_record_and_call_iterator (plugin, stmt, iter, iter_cls); 820 return get_record_and_call_iterator (plugin, stmt, zone, iter, iter_cls);
751}
752
753
754/**
755 * Delete an entire zone (all records). Not used in normal operation.
756 *
757 * @param cls closure (internal context for the plugin)
758 * @param zone zone to delete
759 */
760static void
761namestore_sqlite_delete_zone (void *cls,
762 const struct GNUNET_CRYPTO_ShortHashCode *zone)
763{
764 struct Plugin *plugin = cls;
765 sqlite3_stmt *stmt = plugin->delete_zone;
766 int n;
767
768 if (SQLITE_OK != sqlite3_bind_blob (stmt, 1, zone, sizeof (struct GNUNET_CRYPTO_ShortHashCode), SQLITE_STATIC))
769 {
770 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
771 "sqlite3_bind_XXXX");
772 if (SQLITE_OK != sqlite3_reset (stmt))
773 LOG_SQLITE (plugin,
774 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
775 "sqlite3_reset");
776 return;
777 }
778 n = sqlite3_step (stmt);
779 if (SQLITE_OK != sqlite3_reset (stmt))
780 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
781 "sqlite3_reset");
782 switch (n)
783 {
784 case SQLITE_DONE:
785 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Values deleted\n");
786 break;
787 case SQLITE_BUSY:
788 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK,
789 "sqlite3_step");
790 break;
791 default:
792 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
793 "sqlite3_step");
794 break;
795 }
796} 821}
797 822
798 823
@@ -818,13 +843,13 @@ libgnunet_plugin_namestore_sqlite_init (void *cls)
818 database_shutdown (&plugin); 843 database_shutdown (&plugin);
819 return NULL; 844 return NULL;
820 } 845 }
821 api = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_PluginFunctions)); 846 api = GNUNET_new (struct GNUNET_NAMESTORE_PluginFunctions);
822 api->cls = &plugin; 847 api->cls = &plugin;
823 api->put_records = &namestore_sqlite_put_records; 848 api->cache_block = &namestore_sqlite_cache_block;
824 api->remove_records = &namestore_sqlite_remove_records; 849 api->lookup_block = &namestore_sqlite_lookup_block;
850 api->store_records = &namestore_sqlite_store_records;
825 api->iterate_records = &namestore_sqlite_iterate_records; 851 api->iterate_records = &namestore_sqlite_iterate_records;
826 api->zone_to_name = &namestore_sqlite_zone_to_name; 852 api->zone_to_name = &namestore_sqlite_zone_to_name;
827 api->delete_zone = &namestore_sqlite_delete_zone;
828 LOG (GNUNET_ERROR_TYPE_INFO, 853 LOG (GNUNET_ERROR_TYPE_INFO,
829 _("Sqlite database running\n")); 854 _("Sqlite database running\n"));
830 return api; 855 return api;