diff options
author | Christian Grothoff <christian@grothoff.org> | 2013-08-12 19:28:20 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2013-08-12 19:28:20 +0000 |
commit | 0e2f8eb4285e086281700b53893b1905a52ebc2e (patch) | |
tree | 5bb5b515821e4849b30c91a39f764900e9c35e6f /src/namestore/gnunet-service-namestore.c | |
parent | 5e05019536c0d38bf20f965613636f21ae7c2be6 (diff) | |
download | gnunet-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.c | 260 |
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 | */ | ||
139 | struct 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 | */ |
162 | struct ZoneMonitor | 123 | struct 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; | |||
223 | static struct GNUNET_NAMESTORE_PluginFunctions *GSN_database; | 175 | static struct GNUNET_NAMESTORE_PluginFunctions *GSN_database; |
224 | 176 | ||
225 | /** | 177 | /** |
226 | * Zonefile directory | ||
227 | */ | ||
228 | static char *zonefile_directory; | ||
229 | |||
230 | /** | ||
231 | * Name of the database plugin | 178 | * Name of the database plugin |
232 | */ | 179 | */ |
233 | static char *db_lib_name; | 180 | static char *db_lib_name; |
@@ -248,14 +195,6 @@ static struct NamestoreClient *client_head; | |||
248 | static struct NamestoreClient *client_tail; | 195 | static 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 | */ | ||
256 | static struct GNUNET_CONTAINER_MultiHashMap *zonekeys; | ||
257 | |||
258 | /** | ||
259 | * First active zone monitor. | 198 | * First active zone monitor. |
260 | */ | 199 | */ |
261 | static struct ZoneMonitor *monitor_head; | 200 | static struct ZoneMonitor *monitor_head; |
@@ -271,189 +210,6 @@ static struct ZoneMonitor *monitor_tail; | |||
271 | static struct GNUNET_SERVER_NotificationContext *monitor_nc; | 210 | static 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 | */ | ||
281 | static int | ||
282 | write_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 | */ | ||
362 | static int | ||
363 | zone_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 | */ | ||
390 | static void | ||
391 | learn_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 | */ | ||
430 | static struct GNUNET_TIME_Absolute | ||
431 | get_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); |