diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-02-18 19:03:26 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-02-18 19:03:26 +0000 |
commit | c456c5bb7f9b95d1800ad6e2892a77f40a08493e (patch) | |
tree | 8b04e75f8a65225848816d8e588b28413ff9d758 /src/fs/fs_namespace.c | |
parent | 6d0a62078edfa5c0001acb93d517c674c5124f4e (diff) | |
download | gnunet-c456c5bb7f9b95d1800ad6e2892a77f40a08493e.tar.gz gnunet-c456c5bb7f9b95d1800ad6e2892a77f40a08493e.zip |
make all (?) asynchronously operating FS operations actually cancel-able
Diffstat (limited to 'src/fs/fs_namespace.c')
-rw-r--r-- | src/fs/fs_namespace.c | 439 |
1 files changed, 95 insertions, 344 deletions
diff --git a/src/fs/fs_namespace.c b/src/fs/fs_namespace.c index 9cb8cd5a4..e7cf38800 100644 --- a/src/fs/fs_namespace.c +++ b/src/fs/fs_namespace.c | |||
@@ -30,19 +30,12 @@ | |||
30 | #include "gnunet_fs_service.h" | 30 | #include "gnunet_fs_service.h" |
31 | #include "fs_api.h" | 31 | #include "fs_api.h" |
32 | 32 | ||
33 | #define DEBUG_NAMESPACE GNUNET_EXTRA_LOGGING | ||
34 | |||
35 | 33 | ||
36 | /** | 34 | /** |
37 | * Maximum legal size for an sblock. | 35 | * Maximum legal size for an sblock. |
38 | */ | 36 | */ |
39 | #define MAX_SBLOCK_SIZE (60 * 1024) | 37 | #define MAX_SBLOCK_SIZE (60 * 1024) |
40 | 38 | ||
41 | /** | ||
42 | * Maximum legal size for an nblock. | ||
43 | */ | ||
44 | #define MAX_NBLOCK_SIZE (60 * 1024) | ||
45 | |||
46 | 39 | ||
47 | /** | 40 | /** |
48 | * Return the name of the directory in which we store | 41 | * Return the name of the directory in which we store |
@@ -233,253 +226,6 @@ END: | |||
233 | } | 226 | } |
234 | 227 | ||
235 | 228 | ||
236 | /** | ||
237 | * Context for advertising a namespace. | ||
238 | */ | ||
239 | struct AdvertisementContext | ||
240 | { | ||
241 | /** | ||
242 | * Function to call with the result. | ||
243 | */ | ||
244 | GNUNET_FS_PublishContinuation cont; | ||
245 | |||
246 | /** | ||
247 | * Closure for cont. | ||
248 | */ | ||
249 | void *cont_cls; | ||
250 | |||
251 | /** | ||
252 | * Datastore handle. | ||
253 | */ | ||
254 | struct GNUNET_DATASTORE_Handle *dsh; | ||
255 | |||
256 | /** | ||
257 | * Our KSK URI. | ||
258 | */ | ||
259 | struct GNUNET_FS_Uri *ksk_uri; | ||
260 | |||
261 | /** | ||
262 | * Plaintext. | ||
263 | */ | ||
264 | char *pt; | ||
265 | |||
266 | /** | ||
267 | * NBlock to sign and store. | ||
268 | */ | ||
269 | struct NBlock *nb; | ||
270 | |||
271 | /** | ||
272 | * The namespace. | ||
273 | */ | ||
274 | struct GNUNET_FS_Namespace *ns; | ||
275 | |||
276 | /** | ||
277 | * Block options. | ||
278 | */ | ||
279 | struct GNUNET_FS_BlockOptions bo; | ||
280 | |||
281 | /** | ||
282 | * Number of bytes of plaintext. | ||
283 | */ | ||
284 | size_t pt_size; | ||
285 | |||
286 | /** | ||
287 | * Current keyword offset. | ||
288 | */ | ||
289 | unsigned int pos; | ||
290 | }; | ||
291 | |||
292 | |||
293 | /** | ||
294 | * Disconnect from the datastore. | ||
295 | * | ||
296 | * @param cls datastore handle | ||
297 | * @param tc scheduler context | ||
298 | */ | ||
299 | static void | ||
300 | do_disconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
301 | { | ||
302 | struct GNUNET_DATASTORE_Handle *dsh = cls; | ||
303 | |||
304 | GNUNET_DATASTORE_disconnect (dsh, GNUNET_NO); | ||
305 | } | ||
306 | |||
307 | |||
308 | /** | ||
309 | * Continuation called to notify client about result of the | ||
310 | * operation. | ||
311 | * | ||
312 | * @param cls closure (our struct AdvertismentContext) | ||
313 | * @param success GNUNET_SYSERR on failure | ||
314 | * @param min_expiration minimum expiration time required for content to be stored | ||
315 | * @param msg NULL on success, otherwise an error message | ||
316 | */ | ||
317 | static void | ||
318 | advertisement_cont (void *cls, int success, | ||
319 | struct GNUNET_TIME_Absolute min_expiration, | ||
320 | const char *msg) | ||
321 | { | ||
322 | struct AdvertisementContext *ac = cls; | ||
323 | const char *keyword; | ||
324 | GNUNET_HashCode key; | ||
325 | GNUNET_HashCode query; | ||
326 | struct GNUNET_CRYPTO_AesSessionKey skey; | ||
327 | struct GNUNET_CRYPTO_AesInitializationVector iv; | ||
328 | struct GNUNET_CRYPTO_RsaPrivateKey *pk; | ||
329 | |||
330 | if (GNUNET_OK != success) | ||
331 | { | ||
332 | /* error! */ | ||
333 | GNUNET_SCHEDULER_add_continuation (&do_disconnect, ac->dsh, | ||
334 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); | ||
335 | if (msg == NULL) | ||
336 | { | ||
337 | GNUNET_break (0); | ||
338 | msg = _("Unknown error"); | ||
339 | } | ||
340 | if (ac->cont != NULL) | ||
341 | ac->cont (ac->cont_cls, NULL, msg); | ||
342 | GNUNET_FS_uri_destroy (ac->ksk_uri); | ||
343 | GNUNET_free (ac->pt); | ||
344 | GNUNET_free (ac->nb); | ||
345 | GNUNET_FS_namespace_delete (ac->ns, GNUNET_NO); | ||
346 | GNUNET_free (ac); | ||
347 | return; | ||
348 | } | ||
349 | if (ac->pos == ac->ksk_uri->data.ksk.keywordCount) | ||
350 | { | ||
351 | /* done! */ | ||
352 | GNUNET_SCHEDULER_add_continuation (&do_disconnect, ac->dsh, | ||
353 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); | ||
354 | if (ac->cont != NULL) | ||
355 | ac->cont (ac->cont_cls, ac->ksk_uri, NULL); | ||
356 | GNUNET_FS_uri_destroy (ac->ksk_uri); | ||
357 | GNUNET_free (ac->pt); | ||
358 | GNUNET_free (ac->nb); | ||
359 | GNUNET_FS_namespace_delete (ac->ns, GNUNET_NO); | ||
360 | GNUNET_free (ac); | ||
361 | return; | ||
362 | } | ||
363 | keyword = ac->ksk_uri->data.ksk.keywords[ac->pos++]; | ||
364 | /* first character of keyword indicates if it is | ||
365 | * mandatory or not -- ignore for hashing */ | ||
366 | GNUNET_CRYPTO_hash (&keyword[1], strlen (&keyword[1]), &key); | ||
367 | GNUNET_CRYPTO_hash_to_aes_key (&key, &skey, &iv); | ||
368 | GNUNET_CRYPTO_aes_encrypt (ac->pt, ac->pt_size, &skey, &iv, &ac->nb[1]); | ||
369 | GNUNET_break (GNUNET_OK == | ||
370 | GNUNET_CRYPTO_rsa_sign (ac->ns->key, &ac->nb->ns_purpose, | ||
371 | &ac->nb->ns_signature)); | ||
372 | pk = GNUNET_CRYPTO_rsa_key_create_from_hash (&key); | ||
373 | GNUNET_assert (pk != NULL); | ||
374 | GNUNET_CRYPTO_rsa_key_get_public (pk, &ac->nb->keyspace); | ||
375 | GNUNET_CRYPTO_hash (&ac->nb->keyspace, | ||
376 | sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), | ||
377 | &query); | ||
378 | GNUNET_break (GNUNET_OK == | ||
379 | GNUNET_CRYPTO_rsa_sign (pk, &ac->nb->ksk_purpose, | ||
380 | &ac->nb->ksk_signature)); | ||
381 | GNUNET_CRYPTO_rsa_key_free (pk); | ||
382 | GNUNET_DATASTORE_put (ac->dsh, 0 /* no reservation */ , | ||
383 | &query, ac->pt_size + sizeof (struct NBlock), ac->nb, | ||
384 | GNUNET_BLOCK_TYPE_FS_NBLOCK, ac->bo.content_priority, | ||
385 | ac->bo.anonymity_level, ac->bo.replication_level, | ||
386 | ac->bo.expiration_time, -2, 1, | ||
387 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, &advertisement_cont, | ||
388 | ac); | ||
389 | } | ||
390 | |||
391 | |||
392 | /** | ||
393 | * Publish an advertismement for a namespace. | ||
394 | * | ||
395 | * @param h handle to the file sharing subsystem | ||
396 | * @param ksk_uri keywords to use for advertisment | ||
397 | * @param namespace handle for the namespace that should be advertised | ||
398 | * @param meta meta-data for the namespace advertisement | ||
399 | * @param bo block options | ||
400 | * @param rootEntry name of the root of the namespace | ||
401 | * @param cont continuation | ||
402 | * @param cont_cls closure for cont | ||
403 | */ | ||
404 | void | ||
405 | GNUNET_FS_namespace_advertise (struct GNUNET_FS_Handle *h, | ||
406 | struct GNUNET_FS_Uri *ksk_uri, | ||
407 | struct GNUNET_FS_Namespace *namespace, | ||
408 | const struct GNUNET_CONTAINER_MetaData *meta, | ||
409 | const struct GNUNET_FS_BlockOptions *bo, | ||
410 | const char *rootEntry, | ||
411 | GNUNET_FS_PublishContinuation cont, | ||
412 | void *cont_cls) | ||
413 | { | ||
414 | size_t reslen; | ||
415 | size_t size; | ||
416 | ssize_t mdsize; | ||
417 | struct NBlock *nb; | ||
418 | char *mdst; | ||
419 | struct GNUNET_DATASTORE_Handle *dsh; | ||
420 | struct AdvertisementContext *ctx; | ||
421 | char *pt; | ||
422 | |||
423 | /* create advertisements */ | ||
424 | mdsize = GNUNET_CONTAINER_meta_data_get_serialized_size (meta); | ||
425 | if (-1 == mdsize) | ||
426 | { | ||
427 | cont (cont_cls, NULL, _("Failed to serialize meta data")); | ||
428 | return; | ||
429 | } | ||
430 | reslen = strlen (rootEntry) + 1; | ||
431 | size = mdsize + sizeof (struct NBlock) + reslen; | ||
432 | if (size > MAX_NBLOCK_SIZE) | ||
433 | { | ||
434 | size = MAX_NBLOCK_SIZE; | ||
435 | mdsize = size - sizeof (struct NBlock) - reslen; | ||
436 | } | ||
437 | |||
438 | pt = GNUNET_malloc (mdsize + reslen); | ||
439 | memcpy (pt, rootEntry, reslen); | ||
440 | mdst = &pt[reslen]; | ||
441 | mdsize = | ||
442 | GNUNET_CONTAINER_meta_data_serialize (meta, &mdst, mdsize, | ||
443 | GNUNET_CONTAINER_META_DATA_SERIALIZE_PART); | ||
444 | if (mdsize == -1) | ||
445 | { | ||
446 | GNUNET_break (0); | ||
447 | GNUNET_free (pt); | ||
448 | cont (cont_cls, NULL, _("Failed to serialize meta data")); | ||
449 | return; | ||
450 | } | ||
451 | size = mdsize + sizeof (struct NBlock) + reslen; | ||
452 | nb = GNUNET_malloc (size); | ||
453 | GNUNET_CRYPTO_rsa_key_get_public (namespace->key, &nb->subspace); | ||
454 | nb->ns_purpose.size = | ||
455 | htonl (mdsize + reslen + | ||
456 | sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) + | ||
457 | sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)); | ||
458 | nb->ns_purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_FS_NBLOCK); | ||
459 | nb->ksk_purpose.size = | ||
460 | htonl (size - sizeof (struct GNUNET_CRYPTO_RsaSignature)); | ||
461 | nb->ksk_purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_FS_NBLOCK_KSIG); | ||
462 | dsh = GNUNET_DATASTORE_connect (h->cfg); | ||
463 | if (NULL == dsh) | ||
464 | { | ||
465 | GNUNET_free (nb); | ||
466 | GNUNET_free (pt); | ||
467 | cont (cont_cls, NULL, _("Failed to connect to datastore service")); | ||
468 | return; | ||
469 | } | ||
470 | ctx = GNUNET_malloc (sizeof (struct AdvertisementContext)); | ||
471 | ctx->cont = cont; | ||
472 | ctx->cont_cls = cont_cls; | ||
473 | ctx->dsh = dsh; | ||
474 | ctx->ksk_uri = GNUNET_FS_uri_dup (ksk_uri); | ||
475 | ctx->nb = nb; | ||
476 | ctx->pt = pt; | ||
477 | ctx->pt_size = mdsize + reslen; | ||
478 | ctx->ns = namespace; | ||
479 | ctx->ns->rc++; | ||
480 | ctx->bo = *bo; | ||
481 | advertisement_cont (ctx, GNUNET_OK, GNUNET_TIME_UNIT_ZERO_ABS, NULL); | ||
482 | } | ||
483 | 229 | ||
484 | 230 | ||
485 | /** | 231 | /** |
@@ -557,26 +303,25 @@ GNUNET_FS_namespace_delete (struct GNUNET_FS_Namespace *namespace, int freeze) | |||
557 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "unlink", | 303 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "unlink", |
558 | namespace->filename); | 304 | namespace->filename); |
559 | } | 305 | } |
560 | if (0 == namespace->rc) | 306 | if (0 != namespace->rc) |
307 | return GNUNET_OK; | ||
308 | GNUNET_CRYPTO_rsa_key_free (namespace->key); | ||
309 | GNUNET_free (namespace->filename); | ||
310 | GNUNET_free (namespace->name); | ||
311 | for (i = 0; i < namespace->update_node_count; i++) | ||
561 | { | 312 | { |
562 | GNUNET_CRYPTO_rsa_key_free (namespace->key); | 313 | nsn = namespace->update_nodes[i]; |
563 | GNUNET_free (namespace->filename); | 314 | GNUNET_CONTAINER_meta_data_destroy (nsn->md); |
564 | GNUNET_free (namespace->name); | 315 | GNUNET_FS_uri_destroy (nsn->uri); |
565 | for (i = 0; i < namespace->update_node_count; i++) | 316 | GNUNET_free (nsn->id); |
566 | { | 317 | GNUNET_free (nsn->update); |
567 | nsn = namespace->update_nodes[i]; | 318 | GNUNET_free (nsn); |
568 | GNUNET_CONTAINER_meta_data_destroy (nsn->md); | 319 | } |
569 | GNUNET_FS_uri_destroy (nsn->uri); | 320 | GNUNET_array_grow (namespace->update_nodes, namespace->update_node_count, |
570 | GNUNET_free (nsn->id); | 321 | 0); |
571 | GNUNET_free (nsn->update); | 322 | if (namespace->update_map != NULL) |
572 | GNUNET_free (nsn); | 323 | GNUNET_CONTAINER_multihashmap_destroy (namespace->update_map); |
573 | } | 324 | GNUNET_free (namespace); |
574 | GNUNET_array_grow (namespace->update_nodes, namespace->update_node_count, | ||
575 | 0); | ||
576 | if (namespace->update_map != NULL) | ||
577 | GNUNET_CONTAINER_multihashmap_destroy (namespace->update_map); | ||
578 | GNUNET_free (namespace); | ||
579 | } | ||
580 | return GNUNET_OK; | 325 | return GNUNET_OK; |
581 | } | 326 | } |
582 | 327 | ||
@@ -666,12 +411,10 @@ GNUNET_FS_namespace_list (struct GNUNET_FS_Handle *h, | |||
666 | } | 411 | } |
667 | 412 | ||
668 | 413 | ||
669 | |||
670 | |||
671 | /** | 414 | /** |
672 | * Context for the SKS publication. | 415 | * Context for the SKS publication. |
673 | */ | 416 | */ |
674 | struct PublishSksContext | 417 | struct GNUNET_FS_PublishSksContext |
675 | { | 418 | { |
676 | 419 | ||
677 | /** | 420 | /** |
@@ -705,6 +448,10 @@ struct PublishSksContext | |||
705 | */ | 448 | */ |
706 | void *cont_cls; | 449 | void *cont_cls; |
707 | 450 | ||
451 | /** | ||
452 | * Handle for our datastore request. | ||
453 | */ | ||
454 | struct GNUNET_DATASTORE_QueueEntry *dqe; | ||
708 | }; | 455 | }; |
709 | 456 | ||
710 | 457 | ||
@@ -712,7 +459,7 @@ struct PublishSksContext | |||
712 | * Function called by the datastore API with | 459 | * Function called by the datastore API with |
713 | * the result from the PUT (SBlock) request. | 460 | * the result from the PUT (SBlock) request. |
714 | * | 461 | * |
715 | * @param cls closure of type "struct PublishSksContext*" | 462 | * @param cls closure of type "struct GNUNET_FS_PublishSksContext*" |
716 | * @param success GNUNET_OK on success | 463 | * @param success GNUNET_OK on success |
717 | * @param min_expiration minimum expiration time required for content to be stored | 464 | * @param min_expiration minimum expiration time required for content to be stored |
718 | * @param msg error message (or NULL) | 465 | * @param msg error message (or NULL) |
@@ -722,54 +469,39 @@ sb_put_cont (void *cls, int success, | |||
722 | struct GNUNET_TIME_Absolute min_expiration, | 469 | struct GNUNET_TIME_Absolute min_expiration, |
723 | const char *msg) | 470 | const char *msg) |
724 | { | 471 | { |
725 | struct PublishSksContext *psc = cls; | 472 | struct GNUNET_FS_PublishSksContext *psc = cls; |
726 | GNUNET_HashCode hc; | 473 | GNUNET_HashCode hc; |
727 | 474 | ||
728 | if (NULL != psc->dsh) | 475 | psc->dqe = NULL; |
729 | { | ||
730 | GNUNET_DATASTORE_disconnect (psc->dsh, GNUNET_NO); | ||
731 | psc->dsh = NULL; | ||
732 | } | ||
733 | if (GNUNET_OK != success) | 476 | if (GNUNET_OK != success) |
734 | { | 477 | { |
735 | if (psc->cont != NULL) | 478 | if (NULL != psc->cont) |
736 | psc->cont (psc->cont_cls, NULL, msg); | 479 | psc->cont (psc->cont_cls, NULL, msg); |
480 | GNUNET_FS_publish_sks_cancel (psc); | ||
481 | return; | ||
737 | } | 482 | } |
738 | else | 483 | if (NULL != psc->nsn) |
739 | { | 484 | { |
740 | if (psc->nsn != NULL) | 485 | /* FIXME: this can be done much more |
486 | * efficiently by simply appending to the | ||
487 | * file and overwriting the 4-byte header */ | ||
488 | if (psc->namespace->update_nodes == NULL) | ||
489 | read_update_information_graph (psc->namespace); | ||
490 | GNUNET_array_append (psc->namespace->update_nodes, | ||
491 | psc->namespace->update_node_count, psc->nsn); | ||
492 | if (psc->namespace->update_map != NULL) | ||
741 | { | 493 | { |
742 | /* FIXME: this can be done much more | 494 | GNUNET_CRYPTO_hash (psc->nsn->id, strlen (psc->nsn->id), &hc); |
743 | * efficiently by simply appending to the | 495 | GNUNET_CONTAINER_multihashmap_put (psc->namespace->update_map, &hc, |
744 | * file and overwriting the 4-byte header */ | 496 | psc->nsn, |
745 | if (psc->namespace->update_nodes == NULL) | 497 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); |
746 | read_update_information_graph (psc->namespace); | ||
747 | GNUNET_array_append (psc->namespace->update_nodes, | ||
748 | psc->namespace->update_node_count, psc->nsn); | ||
749 | if (psc->namespace->update_map != NULL) | ||
750 | { | ||
751 | GNUNET_CRYPTO_hash (psc->nsn->id, strlen (psc->nsn->id), &hc); | ||
752 | GNUNET_CONTAINER_multihashmap_put (psc->namespace->update_map, &hc, | ||
753 | psc->nsn, | ||
754 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
755 | } | ||
756 | psc->nsn = NULL; | ||
757 | write_update_information_graph (psc->namespace); | ||
758 | } | 498 | } |
759 | if (psc->cont != NULL) | 499 | psc->nsn = NULL; |
760 | psc->cont (psc->cont_cls, psc->uri, NULL); | 500 | write_update_information_graph (psc->namespace); |
761 | } | ||
762 | GNUNET_FS_namespace_delete (psc->namespace, GNUNET_NO); | ||
763 | GNUNET_FS_uri_destroy (psc->uri); | ||
764 | if (psc->nsn != NULL) | ||
765 | { | ||
766 | GNUNET_CONTAINER_meta_data_destroy (psc->nsn->md); | ||
767 | GNUNET_FS_uri_destroy (psc->nsn->uri); | ||
768 | GNUNET_free (psc->nsn->id); | ||
769 | GNUNET_free (psc->nsn->update); | ||
770 | GNUNET_free (psc->nsn); | ||
771 | } | 501 | } |
772 | GNUNET_free (psc); | 502 | if (NULL != psc->cont) |
503 | psc->cont (psc->cont_cls, psc->uri, NULL); | ||
504 | GNUNET_FS_publish_sks_cancel (psc); | ||
773 | } | 505 | } |
774 | 506 | ||
775 | 507 | ||
@@ -786,8 +518,9 @@ sb_put_cont (void *cls, int success, | |||
786 | * @param options publication options | 518 | * @param options publication options |
787 | * @param cont continuation | 519 | * @param cont continuation |
788 | * @param cont_cls closure for cont | 520 | * @param cont_cls closure for cont |
521 | * @return NULL on error ('cont' will still be called) | ||
789 | */ | 522 | */ |
790 | void | 523 | struct GNUNET_FS_PublishSksContext * |
791 | GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h, | 524 | GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h, |
792 | struct GNUNET_FS_Namespace *namespace, | 525 | struct GNUNET_FS_Namespace *namespace, |
793 | const char *identifier, const char *update, | 526 | const char *identifier, const char *update, |
@@ -797,7 +530,7 @@ GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h, | |||
797 | enum GNUNET_FS_PublishOptions options, | 530 | enum GNUNET_FS_PublishOptions options, |
798 | GNUNET_FS_PublishContinuation cont, void *cont_cls) | 531 | GNUNET_FS_PublishContinuation cont, void *cont_cls) |
799 | { | 532 | { |
800 | struct PublishSksContext *psc; | 533 | struct GNUNET_FS_PublishSksContext *psc; |
801 | struct GNUNET_CRYPTO_AesSessionKey sk; | 534 | struct GNUNET_CRYPTO_AesSessionKey sk; |
802 | struct GNUNET_CRYPTO_AesInitializationVector iv; | 535 | struct GNUNET_CRYPTO_AesInitializationVector iv; |
803 | struct GNUNET_FS_Uri *sks_uri; | 536 | struct GNUNET_FS_Uri *sks_uri; |
@@ -851,8 +584,9 @@ GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h, | |||
851 | { | 584 | { |
852 | GNUNET_break (0); | 585 | GNUNET_break (0); |
853 | GNUNET_free (sb); | 586 | GNUNET_free (sb); |
854 | cont (cont_cls, NULL, _("Internal error.")); | 587 | if (NULL != cont) |
855 | return; | 588 | cont (cont_cls, NULL, _("Internal error.")); |
589 | return NULL; | ||
856 | } | 590 | } |
857 | size = sizeof (struct SBlock) + mdsize + slen + nidlen; | 591 | size = sizeof (struct SBlock) + mdsize + slen + nidlen; |
858 | sb_enc = GNUNET_malloc (size); | 592 | sb_enc = GNUNET_malloc (size); |
@@ -877,18 +611,17 @@ GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h, | |||
877 | GNUNET_assert (GNUNET_OK == | 611 | GNUNET_assert (GNUNET_OK == |
878 | GNUNET_CRYPTO_rsa_sign (namespace->key, &sb_enc->purpose, | 612 | GNUNET_CRYPTO_rsa_sign (namespace->key, &sb_enc->purpose, |
879 | &sb_enc->signature)); | 613 | &sb_enc->signature)); |
880 | psc = GNUNET_malloc (sizeof (struct PublishSksContext)); | 614 | psc = GNUNET_malloc (sizeof (struct GNUNET_FS_PublishSksContext)); |
881 | psc->uri = sks_uri; | 615 | psc->uri = sks_uri; |
882 | psc->cont = cont; | 616 | psc->cont = cont; |
883 | psc->namespace = namespace; | 617 | psc->namespace = GNUNET_FS_namespace_dup (namespace); |
884 | namespace->rc++; | ||
885 | psc->cont_cls = cont_cls; | 618 | psc->cont_cls = cont_cls; |
886 | if (0 != (options & GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY)) | 619 | if (0 != (options & GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY)) |
887 | { | 620 | { |
888 | GNUNET_free (sb_enc); | 621 | GNUNET_free (sb_enc); |
889 | GNUNET_free (sb); | 622 | GNUNET_free (sb); |
890 | sb_put_cont (psc, GNUNET_OK, GNUNET_TIME_UNIT_ZERO_ABS, NULL); | 623 | sb_put_cont (psc, GNUNET_OK, GNUNET_TIME_UNIT_ZERO_ABS, NULL); |
891 | return; | 624 | return NULL; |
892 | } | 625 | } |
893 | psc->dsh = GNUNET_DATASTORE_connect (h->cfg); | 626 | psc->dsh = GNUNET_DATASTORE_connect (h->cfg); |
894 | if (NULL == psc->dsh) | 627 | if (NULL == psc->dsh) |
@@ -896,7 +629,7 @@ GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h, | |||
896 | GNUNET_free (sb_enc); | 629 | GNUNET_free (sb_enc); |
897 | GNUNET_free (sb); | 630 | GNUNET_free (sb); |
898 | sb_put_cont (psc, GNUNET_NO, GNUNET_TIME_UNIT_ZERO_ABS, _("Failed to connect to datastore.")); | 631 | sb_put_cont (psc, GNUNET_NO, GNUNET_TIME_UNIT_ZERO_ABS, _("Failed to connect to datastore.")); |
899 | return; | 632 | return NULL; |
900 | } | 633 | } |
901 | GNUNET_CRYPTO_hash_xor (&sks_uri->data.sks.namespace, &id, &query); | 634 | GNUNET_CRYPTO_hash_xor (&sks_uri->data.sks.namespace, &id, &query); |
902 | if (NULL != update) | 635 | if (NULL != update) |
@@ -907,13 +640,46 @@ GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h, | |||
907 | psc->nsn->md = GNUNET_CONTAINER_meta_data_duplicate (meta); | 640 | psc->nsn->md = GNUNET_CONTAINER_meta_data_duplicate (meta); |
908 | psc->nsn->uri = GNUNET_FS_uri_dup (uri); | 641 | psc->nsn->uri = GNUNET_FS_uri_dup (uri); |
909 | } | 642 | } |
910 | GNUNET_DATASTORE_put (psc->dsh, 0, &sb_enc->identifier, size, sb_enc, | 643 | psc->dqe = GNUNET_DATASTORE_put (psc->dsh, 0, &sb_enc->identifier, size, sb_enc, |
911 | GNUNET_BLOCK_TYPE_FS_SBLOCK, bo->content_priority, | 644 | GNUNET_BLOCK_TYPE_FS_SBLOCK, bo->content_priority, |
912 | bo->anonymity_level, bo->replication_level, | 645 | bo->anonymity_level, bo->replication_level, |
913 | bo->expiration_time, -2, 1, | 646 | bo->expiration_time, -2, 1, |
914 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, &sb_put_cont, psc); | 647 | GNUNET_CONSTANTS_SERVICE_TIMEOUT, &sb_put_cont, psc); |
915 | GNUNET_free (sb); | 648 | GNUNET_free (sb); |
916 | GNUNET_free (sb_enc); | 649 | GNUNET_free (sb_enc); |
650 | return psc; | ||
651 | } | ||
652 | |||
653 | |||
654 | /** | ||
655 | * Abort the SKS publishing operation. | ||
656 | * | ||
657 | * @param sc context of the operation to abort. | ||
658 | */ | ||
659 | void | ||
660 | GNUNET_FS_publish_sks_cancel (struct GNUNET_FS_PublishSksContext *psc) | ||
661 | { | ||
662 | if (NULL != psc->dqe) | ||
663 | { | ||
664 | GNUNET_DATASTORE_cancel (psc->dqe); | ||
665 | psc->dqe = NULL; | ||
666 | } | ||
667 | if (NULL != psc->dsh) | ||
668 | { | ||
669 | GNUNET_DATASTORE_disconnect (psc->dsh, GNUNET_NO); | ||
670 | psc->dsh = NULL; | ||
671 | } | ||
672 | GNUNET_FS_namespace_delete (psc->namespace, GNUNET_NO); | ||
673 | GNUNET_FS_uri_destroy (psc->uri); | ||
674 | if (NULL != psc->nsn) | ||
675 | { | ||
676 | GNUNET_CONTAINER_meta_data_destroy (psc->nsn->md); | ||
677 | GNUNET_FS_uri_destroy (psc->nsn->uri); | ||
678 | GNUNET_free (psc->nsn->id); | ||
679 | GNUNET_free (psc->nsn->update); | ||
680 | GNUNET_free (psc->nsn); | ||
681 | } | ||
682 | GNUNET_free (psc); | ||
917 | } | 683 | } |
918 | 684 | ||
919 | 685 | ||
@@ -1081,10 +847,8 @@ GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Namespace *namespace, | |||
1081 | read_update_information_graph (namespace); | 847 | read_update_information_graph (namespace); |
1082 | if (namespace->update_nodes == NULL) | 848 | if (namespace->update_nodes == NULL) |
1083 | { | 849 | { |
1084 | #if DEBUG_NAMESPACE | ||
1085 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 850 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1086 | "No updateable nodes found for ID `%s'\n", next_id); | 851 | "No updateable nodes found for ID `%s'\n", next_id); |
1087 | #endif | ||
1088 | return; /* no nodes */ | 852 | return; /* no nodes */ |
1089 | } | 853 | } |
1090 | if (namespace->update_map == NULL) | 854 | if (namespace->update_map == NULL) |
@@ -1111,10 +875,8 @@ GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Namespace *namespace, | |||
1111 | &process_update_node, &pc); | 875 | &process_update_node, &pc); |
1112 | return; | 876 | return; |
1113 | } | 877 | } |
1114 | #if DEBUG_NAMESPACE | ||
1115 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 878 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1116 | "Calculating TREEs to find roots of update trees\n"); | 879 | "Calculating TREEs to find roots of update trees\n"); |
1117 | #endif | ||
1118 | /* Find heads of TREEs in update graph */ | 880 | /* Find heads of TREEs in update graph */ |
1119 | nug = ++namespace->nug_gen; | 881 | nug = ++namespace->nug_gen; |
1120 | fc.tree_array = NULL; | 882 | fc.tree_array = NULL; |
@@ -1125,10 +887,8 @@ GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Namespace *namespace, | |||
1125 | nsn = namespace->update_nodes[i]; | 887 | nsn = namespace->update_nodes[i]; |
1126 | if (nsn->nug == nug) | 888 | if (nsn->nug == nug) |
1127 | { | 889 | { |
1128 | #if DEBUG_NAMESPACE | ||
1129 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "TREE of node `%s' is %u\n", nsn->id, | 890 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "TREE of node `%s' is %u\n", nsn->id, |
1130 | nsn->nug); | 891 | nsn->nug); |
1131 | #endif | ||
1132 | continue; /* already placed in TREE */ | 892 | continue; /* already placed in TREE */ |
1133 | } | 893 | } |
1134 | GNUNET_CRYPTO_hash (nsn->update, strlen (nsn->update), &hc); | 894 | GNUNET_CRYPTO_hash (nsn->update, strlen (nsn->update), &hc); |
@@ -1156,11 +916,9 @@ GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Namespace *namespace, | |||
1156 | GNUNET_array_append (fc.tree_array, fc.tree_array_size, nsn); | 916 | GNUNET_array_append (fc.tree_array, fc.tree_array_size, nsn); |
1157 | nsn->tree_id = fc.id; | 917 | nsn->tree_id = fc.id; |
1158 | } | 918 | } |
1159 | #if DEBUG_NAMESPACE | ||
1160 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 919 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1161 | "Starting new TREE %u with node `%s'\n", nsn->tree_id, | 920 | "Starting new TREE %u with node `%s'\n", nsn->tree_id, |
1162 | nsn->id); | 921 | nsn->id); |
1163 | #endif | ||
1164 | /* put all nodes with same identifier into this TREE */ | 922 | /* put all nodes with same identifier into this TREE */ |
1165 | GNUNET_CRYPTO_hash (nsn->id, strlen (nsn->id), &hc); | 923 | GNUNET_CRYPTO_hash (nsn->id, strlen (nsn->id), &hc); |
1166 | fc.id = nsn->tree_id; | 924 | fc.id = nsn->tree_id; |
@@ -1175,28 +933,21 @@ GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Namespace *namespace, | |||
1175 | fc.tree_array[fc.id] = nsn; | 933 | fc.tree_array[fc.id] = nsn; |
1176 | nsn->tree_id = fc.id; | 934 | nsn->tree_id = fc.id; |
1177 | } | 935 | } |
1178 | #if DEBUG_NAMESPACE | ||
1179 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "TREE of node `%s' is %u\n", nsn->id, | 936 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "TREE of node `%s' is %u\n", nsn->id, |
1180 | fc.id); | 937 | fc.id); |
1181 | #endif | ||
1182 | } | 938 | } |
1183 | for (i = 0; i < fc.tree_array_size; i++) | 939 | for (i = 0; i < fc.tree_array_size; i++) |
1184 | { | 940 | { |
1185 | nsn = fc.tree_array[i]; | 941 | nsn = fc.tree_array[i]; |
1186 | if (NULL != nsn) | 942 | if (NULL != nsn) |
1187 | { | 943 | { |
1188 | #if DEBUG_NAMESPACE | ||
1189 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Root of TREE %u is node `%s'\n", i, | 944 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Root of TREE %u is node `%s'\n", i, |
1190 | nsn->id); | 945 | nsn->id); |
1191 | #endif | ||
1192 | |||
1193 | ip (ip_cls, nsn->id, nsn->uri, nsn->md, nsn->update); | 946 | ip (ip_cls, nsn->id, nsn->uri, nsn->md, nsn->update); |
1194 | } | 947 | } |
1195 | } | 948 | } |
1196 | GNUNET_array_grow (fc.tree_array, fc.tree_array_size, 0); | 949 | GNUNET_array_grow (fc.tree_array, fc.tree_array_size, 0); |
1197 | #if DEBUG_NAMESPACE | ||
1198 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Done processing TREEs\n"); | 950 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Done processing TREEs\n"); |
1199 | #endif | ||
1200 | } | 951 | } |
1201 | 952 | ||
1202 | 953 | ||