aboutsummaryrefslogtreecommitdiff
path: root/src/namestore/gnunet-service-namestore.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2013-08-12 19:28:20 +0000
committerChristian Grothoff <christian@grothoff.org>2013-08-12 19:28:20 +0000
commit0e2f8eb4285e086281700b53893b1905a52ebc2e (patch)
tree5bb5b515821e4849b30c91a39f764900e9c35e6f /src/namestore/gnunet-service-namestore.c
parent5e05019536c0d38bf20f965613636f21ae7c2be6 (diff)
downloadgnunet-0e2f8eb4285e086281700b53893b1905a52ebc2e.tar.gz
gnunet-0e2f8eb4285e086281700b53893b1905a52ebc2e.zip
-more work on new namestore API
Diffstat (limited to 'src/namestore/gnunet-service-namestore.c')
-rw-r--r--src/namestore/gnunet-service-namestore.c260
1 files changed, 4 insertions, 256 deletions
diff --git a/src/namestore/gnunet-service-namestore.c b/src/namestore/gnunet-service-namestore.c
index 749552dca..4b1345be7 100644
--- a/src/namestore/gnunet-service-namestore.c
+++ b/src/namestore/gnunet-service-namestore.c
@@ -62,16 +62,9 @@ struct ZoneIteration
62 struct NamestoreClient *client; 62 struct NamestoreClient *client;
63 63
64 /** 64 /**
65 * GNUNET_YES if we iterate over a specific zone 65 * Key of the zone we are iterating over.
66 * GNUNET_NO if we iterate over all zones
67 */ 66 */
68 int has_zone; 67 struct GNUNET_CRYPTO_EccPrivateKey zone;
69
70 /**
71 * Hash of the specific zone if 'has_zone' is GNUNET_YES,
72 * othwerwise set to '\0'
73 */
74 struct GNUNET_CRYPTO_ShortHashCode zone;
75 68
76 /** 69 /**
77 * The operation id fot the zone iteration in the response for the client 70 * The operation id fot the zone iteration in the response for the client
@@ -87,15 +80,6 @@ struct ZoneIteration
87 */ 80 */
88 uint32_t offset; 81 uint32_t offset;
89 82
90 /**
91 * Which flags must be included
92 */
93 uint16_t must_have_flags;
94
95 /**
96 * Which flags must not be included
97 */
98 uint16_t must_not_have_flags;
99}; 83};
100 84
101 85
@@ -134,29 +118,6 @@ struct NamestoreClient
134 118
135 119
136/** 120/**
137 * A container struct to store information belonging to a zone crypto key pair
138 */
139struct GNUNET_NAMESTORE_CryptoContainer
140{
141 /**
142 * Filename where to store the container
143 */
144 char *filename;
145
146 /**
147 * Short hash of the zone's public key
148 */
149 struct GNUNET_CRYPTO_ShortHashCode zone;
150
151 /**
152 * Zone's private key
153 */
154 struct GNUNET_CRYPTO_EccPrivateKey *privkey;
155
156};
157
158
159/**
160 * A namestore monitor. 121 * A namestore monitor.
161 */ 122 */
162struct ZoneMonitor 123struct ZoneMonitor
@@ -177,16 +138,9 @@ struct ZoneMonitor
177 struct GNUNET_SERVER_Client *client; 138 struct GNUNET_SERVER_Client *client;
178 139
179 /** 140 /**
180 * GNUNET_YES if we monitor over a specific zone 141 * Private key of the zone.
181 * GNUNET_NO if we monitor all zones
182 */ 142 */
183 int has_zone; 143 struct GNUNET_CRYPTO_EccPrivateKey zone;
184
185 /**
186 * Hash of the specific zone if 'has_zone' is GNUNET_YES,
187 * othwerwise set to '\0'
188 */
189 struct GNUNET_CRYPTO_ShortHashCode zone;
190 144
191 /** 145 /**
192 * The operation id fot the zone iteration in the response for the client 146 * The operation id fot the zone iteration in the response for the client
@@ -210,8 +164,6 @@ struct ZoneMonitor
210}; 164};
211 165
212 166
213
214
215/** 167/**
216 * Configuration handle. 168 * Configuration handle.
217 */ 169 */
@@ -223,11 +175,6 @@ static const struct GNUNET_CONFIGURATION_Handle *GSN_cfg;
223static struct GNUNET_NAMESTORE_PluginFunctions *GSN_database; 175static struct GNUNET_NAMESTORE_PluginFunctions *GSN_database;
224 176
225/** 177/**
226 * Zonefile directory
227 */
228static char *zonefile_directory;
229
230/**
231 * Name of the database plugin 178 * Name of the database plugin
232 */ 179 */
233static char *db_lib_name; 180static char *db_lib_name;
@@ -248,14 +195,6 @@ static struct NamestoreClient *client_head;
248static struct NamestoreClient *client_tail; 195static struct NamestoreClient *client_tail;
249 196
250/** 197/**
251 * Hashmap containing the zone keys this namestore has is authoritative for
252 *
253 * Keys are the GNUNET_CRYPTO_HashCode of the GNUNET_CRYPTO_ShortHashCode
254 * The values are 'struct GNUNET_NAMESTORE_CryptoContainer *'
255 */
256static struct GNUNET_CONTAINER_MultiHashMap *zonekeys;
257
258/**
259 * First active zone monitor. 198 * First active zone monitor.
260 */ 199 */
261static struct ZoneMonitor *monitor_head; 200static struct ZoneMonitor *monitor_head;
@@ -271,189 +210,6 @@ static struct ZoneMonitor *monitor_tail;
271static struct GNUNET_SERVER_NotificationContext *monitor_nc; 210static struct GNUNET_SERVER_NotificationContext *monitor_nc;
272 211
273 212
274/**
275 * Writes the encrypted private key of a zone in a file
276 *
277 * @param filename where to store the zone
278 * @param c the crypto container containing private key of the zone
279 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
280 */
281static int
282write_key_to_file (const char *filename,
283 struct GNUNET_NAMESTORE_CryptoContainer *c)
284{
285 struct GNUNET_CRYPTO_EccPrivateKey *ret = c->privkey;
286 struct GNUNET_DISK_FileHandle *fd;
287 struct GNUNET_CRYPTO_ShortHashCode zone;
288 struct GNUNET_CRYPTO_EccPublicKey pubkey;
289 struct GNUNET_CRYPTO_EccPrivateKey *privkey;
290
291 fd = GNUNET_DISK_file_open (filename,
292 GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_FAILIFEXISTS,
293 GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE);
294 if ( (NULL == fd) && (EEXIST == errno) )
295 {
296 privkey = GNUNET_CRYPTO_ecc_key_create_from_file (filename);
297 if (NULL == privkey)
298 {
299 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
300 _("Failed to write zone key to file `%s': %s\n"),
301 filename,
302 _("file exists but reading key failed"));
303 return GNUNET_SYSERR;
304 }
305 GNUNET_CRYPTO_ecc_key_get_public (privkey, &pubkey);
306 GNUNET_CRYPTO_short_hash (&pubkey,
307 sizeof (struct GNUNET_CRYPTO_EccPublicKey),
308 &zone);
309 GNUNET_CRYPTO_ecc_key_free (privkey);
310 if (0 == memcmp (&zone, &c->zone, sizeof(zone)))
311 {
312 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
313 "File zone `%s' containing this key already exists\n",
314 GNUNET_NAMESTORE_short_h2s (&zone));
315 return GNUNET_OK;
316 }
317 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
318 _("Failed to write zone key to file `%s': %s\n"),
319 filename,
320 _("file exists with different key"));
321 return GNUNET_OK;
322 }
323 if (NULL == fd)
324 {
325 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "open", filename);
326 return GNUNET_SYSERR;
327 }
328 if (GNUNET_YES !=
329 GNUNET_DISK_file_lock (fd, 0,
330 sizeof (struct GNUNET_CRYPTO_EccPrivateKey),
331 GNUNET_YES))
332 {
333 GNUNET_break (GNUNET_YES == GNUNET_DISK_file_close (fd));
334 return GNUNET_SYSERR;
335 }
336 GNUNET_assert (sizeof (struct GNUNET_CRYPTO_EccPrivateKey) ==
337 GNUNET_DISK_file_write (fd, ret,
338 sizeof (struct GNUNET_CRYPTO_EccPrivateKey)));
339 GNUNET_DISK_file_sync (fd);
340 if (GNUNET_YES !=
341 GNUNET_DISK_file_unlock (fd, 0,
342 sizeof (struct GNUNET_CRYPTO_EccPrivateKey)))
343 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
344 GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd));
345 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
346 "Stored zonekey for zone `%s' in file `%s'\n",
347 GNUNET_NAMESTORE_short_h2s(&c->zone), c->filename);
348 return GNUNET_OK;
349}
350
351
352/**
353 * Write allthe given zone key to disk and then removes the entry from the
354 * 'zonekeys' hash map.
355 *
356 * @param cls unused
357 * @param key zone key
358 * @param value 'struct GNUNET_NAMESTORE_CryptoContainer' containing the private
359 * key
360 * @return GNUNET_OK to continue iteration
361 */
362static int
363zone_to_disk_it (void *cls,
364 const struct GNUNET_HashCode *key,
365 void *value)
366{
367 struct GNUNET_NAMESTORE_CryptoContainer *c = value;
368
369 if (NULL == c->filename)
370 GNUNET_asprintf(&c->filename,
371 "%s/%s.zkey",
372 zonefile_directory,
373 GNUNET_NAMESTORE_short_h2s (&c->zone));
374 (void) write_key_to_file(c->filename, c);
375 GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap_remove (zonekeys, key, value));
376 GNUNET_CRYPTO_ecc_key_free (c->privkey);
377 GNUNET_free (c->filename);
378 GNUNET_free (c);
379 return GNUNET_OK;
380}
381
382
383/**
384 * Add the given private key to the set of private keys
385 * this namestore can use to sign records when needed.
386 *
387 * @param pkey private key to add to our list (reference will
388 * be taken over or freed and should not be used afterwards)
389 */
390static void
391learn_private_key (struct GNUNET_CRYPTO_EccPrivateKey *pkey)
392{
393 struct GNUNET_CRYPTO_EccPublicKey pub;
394 struct GNUNET_HashCode long_hash;
395 struct GNUNET_CRYPTO_ShortHashCode pubkey_hash;
396 struct GNUNET_NAMESTORE_CryptoContainer *cc;
397
398 GNUNET_CRYPTO_ecc_key_get_public (pkey, &pub);
399 GNUNET_CRYPTO_short_hash (&pub,
400 sizeof (struct GNUNET_CRYPTO_EccPublicKey),
401 &pubkey_hash);
402 GNUNET_CRYPTO_short_hash_double (&pubkey_hash, &long_hash);
403
404 if (GNUNET_NO != GNUNET_CONTAINER_multihashmap_contains(zonekeys, &long_hash))
405 {
406 GNUNET_CRYPTO_ecc_key_free (pkey);
407 return;
408 }
409 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
410 "Received new private key for zone `%s'\n",
411 GNUNET_NAMESTORE_short_h2s(&pubkey_hash));
412 cc = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_CryptoContainer));
413 cc->privkey = pkey;
414 cc->zone = pubkey_hash;
415 GNUNET_assert (GNUNET_YES ==
416 GNUNET_CONTAINER_multihashmap_put(zonekeys, &long_hash, cc,
417 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
418}
419
420
421/**
422 * Returns the expiration time of the given block of records. The block
423 * expiration time is the expiration time of the block with smallest
424 * expiration time.
425 *
426 * @param rd_count number of records given in 'rd'
427 * @param rd array of records
428 * @return absolute expiration time
429 */
430static struct GNUNET_TIME_Absolute
431get_block_expiration_time (unsigned int rd_count, const struct GNUNET_NAMESTORE_RecordData *rd)
432{
433 unsigned int c;
434 struct GNUNET_TIME_Absolute expire;
435 struct GNUNET_TIME_Absolute at;
436 struct GNUNET_TIME_Relative rt;
437
438 if (NULL == rd)
439 return GNUNET_TIME_UNIT_ZERO_ABS;
440 expire = GNUNET_TIME_UNIT_FOREVER_ABS;
441 for (c = 0; c < rd_count; c++)
442 {
443 if (0 != (rd[c].flags & GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION))
444 {
445 rt.rel_value_us = rd[c].expiration_time;
446 at = GNUNET_TIME_relative_to_absolute (rt);
447 }
448 else
449 {
450 at.abs_value_us = rd[c].expiration_time;
451 }
452 expire = GNUNET_TIME_absolute_min (at, expire);
453 }
454 return expire;
455}
456
457 213
458/** 214/**
459 * Task run during shutdown. 215 * Task run during shutdown.
@@ -473,12 +229,6 @@ cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
473 GNUNET_SERVER_notification_context_destroy (snc); 229 GNUNET_SERVER_notification_context_destroy (snc);
474 snc = NULL; 230 snc = NULL;
475 } 231 }
476 if (NULL != zonekeys)
477 {
478 GNUNET_CONTAINER_multihashmap_iterate (zonekeys, &zone_to_disk_it, NULL);
479 GNUNET_CONTAINER_multihashmap_destroy (zonekeys);
480 zonekeys = NULL;
481 }
482 while (NULL != (nc = client_head)) 232 while (NULL != (nc = client_head))
483 { 233 {
484 while (NULL != (no = nc->op_head)) 234 while (NULL != (no = nc->op_head))
@@ -492,8 +242,6 @@ cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
492 GNUNET_break (NULL == GNUNET_PLUGIN_unload (db_lib_name, GSN_database)); 242 GNUNET_break (NULL == GNUNET_PLUGIN_unload (db_lib_name, GSN_database));
493 GNUNET_free (db_lib_name); 243 GNUNET_free (db_lib_name);
494 db_lib_name = NULL; 244 db_lib_name = NULL;
495 GNUNET_free_non_null (zonefile_directory);
496 zonefile_directory = NULL;
497 if (NULL != monitor_nc) 245 if (NULL != monitor_nc)
498 { 246 {
499 GNUNET_SERVER_notification_context_destroy (monitor_nc); 247 GNUNET_SERVER_notification_context_destroy (monitor_nc);