diff options
author | Christian Grothoff <christian@grothoff.org> | 2013-08-22 07:28:58 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2013-08-22 07:28:58 +0000 |
commit | 35904869bbbecaac43611a0d7b4b78e7735a90bf (patch) | |
tree | 04b76dcab6a97a1c4d41fbfda81f46893db543d0 /src/gns | |
parent | aa590fa228c0efd30c5d6523bb064b4d4421752e (diff) | |
download | gnunet-35904869bbbecaac43611a0d7b4b78e7735a90bf.tar.gz gnunet-35904869bbbecaac43611a0d7b4b78e7735a90bf.zip |
-move shorten logic to its own file
Diffstat (limited to 'src/gns')
-rw-r--r-- | src/gns/Makefile.am | 1 | ||||
-rw-r--r-- | src/gns/gnunet-service-gns.c | 5 | ||||
-rw-r--r-- | src/gns/gnunet-service-gns_resolver.c | 537 | ||||
-rw-r--r-- | src/gns/gnunet-service-gns_shorten.c | 568 | ||||
-rw-r--r-- | src/gns/gnunet-service-gns_shorten.h | 66 |
5 files changed, 641 insertions, 536 deletions
diff --git a/src/gns/Makefile.am b/src/gns/Makefile.am index 10177996e..c2e4264b5 100644 --- a/src/gns/Makefile.am +++ b/src/gns/Makefile.am | |||
@@ -129,6 +129,7 @@ w32nsp_resolve_LDADD = -lws2_32 | |||
129 | gnunet_service_gns_SOURCES = \ | 129 | gnunet_service_gns_SOURCES = \ |
130 | gnunet-service-gns.c \ | 130 | gnunet-service-gns.c \ |
131 | gnunet-service-gns_resolver.c gnunet-service-gns_resolver.h \ | 131 | gnunet-service-gns_resolver.c gnunet-service-gns_resolver.h \ |
132 | gnunet-service-gns_shorten.c gnunet-service-gns_shorten.h \ | ||
132 | gnunet-service-gns_interceptor.c gnunet-service-gns_interceptor.h | 133 | gnunet-service-gns_interceptor.c gnunet-service-gns_interceptor.h |
133 | gnunet_service_gns_LDADD = \ | 134 | gnunet_service_gns_LDADD = \ |
134 | -lm \ | 135 | -lm \ |
diff --git a/src/gns/gnunet-service-gns.c b/src/gns/gnunet-service-gns.c index 583a5131a..b21584350 100644 --- a/src/gns/gnunet-service-gns.c +++ b/src/gns/gnunet-service-gns.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include "gnunet_statistics_service.h" | 34 | #include "gnunet_statistics_service.h" |
35 | #include "gns.h" | 35 | #include "gns.h" |
36 | #include "gnunet-service-gns_resolver.h" | 36 | #include "gnunet-service-gns_resolver.h" |
37 | #include "gnunet-service-gns_shorten.h" | ||
37 | #include "gnunet-service-gns_interceptor.h" | 38 | #include "gnunet-service-gns_interceptor.h" |
38 | #include "gnunet_protocols.h" | 39 | #include "gnunet_protocols.h" |
39 | 40 | ||
@@ -214,6 +215,7 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
214 | 215 | ||
215 | GNS_interceptor_done (); | 216 | GNS_interceptor_done (); |
216 | GNS_resolver_done (); | 217 | GNS_resolver_done (); |
218 | GNS_shorten_done (); | ||
217 | if (NULL != statistics) | 219 | if (NULL != statistics) |
218 | { | 220 | { |
219 | GNUNET_STATISTICS_destroy (statistics, GNUNET_NO); | 221 | GNUNET_STATISTICS_destroy (statistics, GNUNET_NO); |
@@ -718,11 +720,10 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, | |||
718 | return; | 720 | return; |
719 | } | 721 | } |
720 | } | 722 | } |
721 | /* FIXME: install client disconnect handle to clean up pending | ||
722 | lookups on client disconnect! */ | ||
723 | GNS_resolver_init (namestore_handle, dht_handle, | 723 | GNS_resolver_init (namestore_handle, dht_handle, |
724 | c, | 724 | c, |
725 | max_parallel_bg_queries); | 725 | max_parallel_bg_queries); |
726 | GNS_shorten_init (namestore_handle, dht_handle); | ||
726 | GNUNET_SERVER_disconnect_notify (server, | 727 | GNUNET_SERVER_disconnect_notify (server, |
727 | ¬ify_client_disconnect, | 728 | ¬ify_client_disconnect, |
728 | NULL); | 729 | NULL); |
diff --git a/src/gns/gnunet-service-gns_resolver.c b/src/gns/gnunet-service-gns_resolver.c index b131a4750..0fb6ffbd1 100644 --- a/src/gns/gnunet-service-gns_resolver.c +++ b/src/gns/gnunet-service-gns_resolver.c | |||
@@ -53,7 +53,6 @@ | |||
53 | */ | 53 | */ |
54 | #include "platform.h" | 54 | #include "platform.h" |
55 | #include "gnunet_util_lib.h" | 55 | #include "gnunet_util_lib.h" |
56 | #include "gnunet_transport_service.h" | ||
57 | #include "gnunet_dnsstub_lib.h" | 56 | #include "gnunet_dnsstub_lib.h" |
58 | #include "gnunet_dht_service.h" | 57 | #include "gnunet_dht_service.h" |
59 | #include "gnunet_namestore_service.h" | 58 | #include "gnunet_namestore_service.h" |
@@ -63,6 +62,7 @@ | |||
63 | #include "gnunet_gns_service.h" | 62 | #include "gnunet_gns_service.h" |
64 | #include "gns.h" | 63 | #include "gns.h" |
65 | #include "gnunet-service-gns_resolver.h" | 64 | #include "gnunet-service-gns_resolver.h" |
65 | #include "gnunet-service-gns_shorten.h" | ||
66 | #include "gnunet_vpn_service.h" | 66 | #include "gnunet_vpn_service.h" |
67 | 67 | ||
68 | 68 | ||
@@ -159,53 +159,6 @@ struct AuthorityChain | |||
159 | 159 | ||
160 | 160 | ||
161 | /** | 161 | /** |
162 | * Resolution status indicator | ||
163 | */ | ||
164 | enum ResolutionStatus | ||
165 | { | ||
166 | /** | ||
167 | * the name to lookup exists | ||
168 | */ | ||
169 | RSL_RECORD_EXISTS = 1, | ||
170 | |||
171 | /** | ||
172 | * the name in the record expired | ||
173 | */ | ||
174 | RSL_RECORD_EXPIRED = 2, | ||
175 | |||
176 | /** | ||
177 | * resolution timed out | ||
178 | */ | ||
179 | RSL_TIMED_OUT = 4, | ||
180 | |||
181 | /** | ||
182 | * Found VPN delegation | ||
183 | */ | ||
184 | RSL_DELEGATE_VPN = 8, | ||
185 | |||
186 | /** | ||
187 | * Found NS delegation | ||
188 | */ | ||
189 | RSL_DELEGATE_NS = 16, | ||
190 | |||
191 | /** | ||
192 | * Found PKEY delegation | ||
193 | */ | ||
194 | RSL_DELEGATE_PKEY = 32, | ||
195 | |||
196 | /** | ||
197 | * Found CNAME record | ||
198 | */ | ||
199 | RSL_CNAME_FOUND = 64, | ||
200 | |||
201 | /** | ||
202 | * Found PKEY has been revoked | ||
203 | */ | ||
204 | RSL_PKEY_REVOKED = 128 | ||
205 | }; | ||
206 | |||
207 | |||
208 | /** | ||
209 | * A result we got from DNS. | 162 | * A result we got from DNS. |
210 | */ | 163 | */ |
211 | struct DnsResult | 164 | struct DnsResult |
@@ -402,60 +355,6 @@ struct GNS_ResolverHandle | |||
402 | 355 | ||
403 | 356 | ||
404 | /** | 357 | /** |
405 | * Handle for a PSEU lookup used to shorten names. | ||
406 | */ | ||
407 | struct GetPseuAuthorityHandle | ||
408 | { | ||
409 | /** | ||
410 | * DLL | ||
411 | */ | ||
412 | struct GetPseuAuthorityHandle *next; | ||
413 | |||
414 | /** | ||
415 | * DLL | ||
416 | */ | ||
417 | struct GetPseuAuthorityHandle *prev; | ||
418 | |||
419 | /** | ||
420 | * Private key of the (shorten) zone to store the resulting | ||
421 | * pseudonym in. | ||
422 | */ | ||
423 | struct GNUNET_CRYPTO_EccPrivateKey shorten_zone_key; | ||
424 | |||
425 | /** | ||
426 | * Original label (used if no PSEU record is found). | ||
427 | */ | ||
428 | char label[GNUNET_DNSPARSER_MAX_LABEL_LENGTH + 1]; | ||
429 | |||
430 | /** | ||
431 | * Label we are currently trying out (during #perform_pseu_lookup). | ||
432 | */ | ||
433 | char *current_label; | ||
434 | |||
435 | /** | ||
436 | * The zone for which we are trying to find the PSEU record. | ||
437 | */ | ||
438 | struct GNUNET_CRYPTO_EccPublicKey target_zone; | ||
439 | |||
440 | /** | ||
441 | * Handle for DHT lookups. Should be NULL if no lookups are in progress | ||
442 | */ | ||
443 | struct GNUNET_DHT_GetHandle *get_handle; | ||
444 | |||
445 | /** | ||
446 | * Handle to namestore request | ||
447 | */ | ||
448 | struct GNUNET_NAMESTORE_QueueEntry *namestore_task; | ||
449 | |||
450 | /** | ||
451 | * Task to abort DHT lookup operation. | ||
452 | */ | ||
453 | GNUNET_SCHEDULER_TaskIdentifier timeout_task; | ||
454 | |||
455 | }; | ||
456 | |||
457 | |||
458 | /** | ||
459 | * Our handle to the namestore service | 358 | * Our handle to the namestore service |
460 | */ | 359 | */ |
461 | static struct GNUNET_NAMESTORE_Handle *namestore_handle; | 360 | static struct GNUNET_NAMESTORE_Handle *namestore_handle; |
@@ -486,16 +385,6 @@ static struct GNUNET_CONTAINER_Heap *dht_lookup_heap; | |||
486 | static unsigned long long max_allowed_background_queries; | 385 | static unsigned long long max_allowed_background_queries; |
487 | 386 | ||
488 | /** | 387 | /** |
489 | * Head of PSEU/shorten operations list. | ||
490 | */ | ||
491 | struct GetPseuAuthorityHandle *gph_head; | ||
492 | |||
493 | /** | ||
494 | * Tail of PSEU/shorten operations list. | ||
495 | */ | ||
496 | struct GetPseuAuthorityHandle *gph_tail; | ||
497 | |||
498 | /** | ||
499 | * Head of resolver lookup list | 388 | * Head of resolver lookup list |
500 | */ | 389 | */ |
501 | static struct GNS_ResolverHandle *rlh_head; | 390 | static struct GNS_ResolverHandle *rlh_head; |
@@ -576,425 +465,6 @@ is_canonical (const char *name) | |||
576 | } | 465 | } |
577 | 466 | ||
578 | 467 | ||
579 | /* ******************** Shortening logic ************************ */ | ||
580 | |||
581 | |||
582 | /** | ||
583 | * Cleanup a 'struct GetPseuAuthorityHandle', terminating all | ||
584 | * pending activities. | ||
585 | * | ||
586 | * @param gph handle to terminate | ||
587 | */ | ||
588 | static void | ||
589 | free_get_pseu_authority_handle (struct GetPseuAuthorityHandle *gph) | ||
590 | { | ||
591 | if (NULL != gph->get_handle) | ||
592 | { | ||
593 | GNUNET_DHT_get_stop (gph->get_handle); | ||
594 | gph->get_handle = NULL; | ||
595 | } | ||
596 | if (NULL != gph->namestore_task) | ||
597 | { | ||
598 | GNUNET_NAMESTORE_cancel (gph->namestore_task); | ||
599 | gph->namestore_task = NULL; | ||
600 | } | ||
601 | if (GNUNET_SCHEDULER_NO_TASK != gph->timeout_task) | ||
602 | { | ||
603 | GNUNET_SCHEDULER_cancel (gph->timeout_task); | ||
604 | gph->timeout_task = GNUNET_SCHEDULER_NO_TASK; | ||
605 | } | ||
606 | GNUNET_CONTAINER_DLL_remove (gph_head, gph_tail, gph); | ||
607 | GNUNET_free_non_null (gph->current_label); | ||
608 | GNUNET_free (gph); | ||
609 | } | ||
610 | |||
611 | |||
612 | /** | ||
613 | * Continuation for pkey record creation (shorten) | ||
614 | * | ||
615 | * @param cls a GetPseuAuthorityHandle | ||
616 | * @param success unused | ||
617 | * @param emsg unused | ||
618 | */ | ||
619 | static void | ||
620 | create_pkey_cont (void* cls, | ||
621 | int32_t success, | ||
622 | const char *emsg) | ||
623 | { | ||
624 | struct GetPseuAuthorityHandle* gph = cls; | ||
625 | |||
626 | gph->namestore_task = NULL; | ||
627 | free_get_pseu_authority_handle (gph); | ||
628 | } | ||
629 | |||
630 | |||
631 | /** | ||
632 | * Namestore calls this function if we have record for this name. | ||
633 | * (or with rd_count=0 to indicate no matches). | ||
634 | * | ||
635 | * @param cls the pending query | ||
636 | * @param rd_count the number of records with 'name' | ||
637 | * @param rd the record data | ||
638 | */ | ||
639 | static void | ||
640 | process_pseu_lookup_ns (void *cls, | ||
641 | unsigned int rd_count, | ||
642 | const struct GNUNET_NAMESTORE_RecordData *rd); | ||
643 | |||
644 | |||
645 | /** | ||
646 | * We obtained a result for our query to the shorten zone from | ||
647 | * the namestore. Try to decrypt. | ||
648 | * | ||
649 | * @param cls the handle to our shorten operation | ||
650 | * @param block resulting encrypted block | ||
651 | */ | ||
652 | static void | ||
653 | process_pseu_block_ns (void *cls, | ||
654 | const struct GNUNET_NAMESTORE_Block *block) | ||
655 | { | ||
656 | struct GetPseuAuthorityHandle *gph = cls; | ||
657 | struct GNUNET_CRYPTO_EccPublicKey pub; | ||
658 | |||
659 | gph->namestore_task = NULL; | ||
660 | if (NULL == block) | ||
661 | { | ||
662 | process_pseu_lookup_ns (gph, 0, NULL); | ||
663 | return; | ||
664 | } | ||
665 | GNUNET_CRYPTO_ecc_key_get_public (&gph->shorten_zone_key, | ||
666 | &pub); | ||
667 | if (GNUNET_OK != | ||
668 | GNUNET_NAMESTORE_block_decrypt (block, | ||
669 | &pub, | ||
670 | gph->current_label, | ||
671 | &process_pseu_lookup_ns, | ||
672 | gph)) | ||
673 | { | ||
674 | GNUNET_break (0); | ||
675 | free_get_pseu_authority_handle (gph); | ||
676 | return; | ||
677 | } | ||
678 | } | ||
679 | |||
680 | |||
681 | /** | ||
682 | * Lookup in the namestore for the shorten zone the given label. | ||
683 | * | ||
684 | * @param gph the handle to our shorten operation | ||
685 | * @param label the label to lookup | ||
686 | */ | ||
687 | static void | ||
688 | perform_pseu_lookup (struct GetPseuAuthorityHandle *gph, | ||
689 | const char *label) | ||
690 | { | ||
691 | struct GNUNET_CRYPTO_EccPublicKey pub; | ||
692 | struct GNUNET_HashCode query; | ||
693 | |||
694 | GNUNET_CRYPTO_ecc_key_get_public (&gph->shorten_zone_key, | ||
695 | &pub); | ||
696 | GNUNET_free_non_null (gph->current_label); | ||
697 | gph->current_label = GNUNET_strdup (label); | ||
698 | GNUNET_NAMESTORE_query_from_public_key (&pub, | ||
699 | label, | ||
700 | &query); | ||
701 | gph->namestore_task = GNUNET_NAMESTORE_lookup_block (namestore_handle, | ||
702 | &query, | ||
703 | &process_pseu_block_ns, | ||
704 | gph); | ||
705 | } | ||
706 | |||
707 | |||
708 | /** | ||
709 | * Namestore calls this function if we have record for this name. | ||
710 | * (or with rd_count=0 to indicate no matches). | ||
711 | * | ||
712 | * @param cls the pending query | ||
713 | * @param rd_count the number of records with 'name' | ||
714 | * @param rd the record data | ||
715 | */ | ||
716 | static void | ||
717 | process_pseu_lookup_ns (void *cls, | ||
718 | unsigned int rd_count, | ||
719 | const struct GNUNET_NAMESTORE_RecordData *rd) | ||
720 | { | ||
721 | struct GetPseuAuthorityHandle *gph = cls; | ||
722 | struct GNUNET_NAMESTORE_RecordData new_pkey; | ||
723 | |||
724 | gph->namestore_task = NULL; | ||
725 | if (rd_count > 0) | ||
726 | { | ||
727 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
728 | "Name `%s' already taken, cannot shorten.\n", | ||
729 | gph->current_label); | ||
730 | /* if this was not yet the original label, try one more | ||
731 | time, this time not using PSEU but the original label */ | ||
732 | if (0 == strcmp (gph->current_label, | ||
733 | gph->label)) | ||
734 | { | ||
735 | free_get_pseu_authority_handle (gph); | ||
736 | } | ||
737 | else | ||
738 | { | ||
739 | perform_pseu_lookup (gph, gph->label); | ||
740 | } | ||
741 | return; | ||
742 | } | ||
743 | /* name is available */ | ||
744 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
745 | "Shortening `%s' to `%s'\n", | ||
746 | GNUNET_NAMESTORE_z2s (&gph->target_zone), | ||
747 | gph->current_label); | ||
748 | new_pkey.expiration_time = UINT64_MAX; | ||
749 | new_pkey.data_size = sizeof (struct GNUNET_CRYPTO_EccPublicKey); | ||
750 | new_pkey.data = &gph->target_zone; | ||
751 | new_pkey.record_type = GNUNET_NAMESTORE_TYPE_PKEY; | ||
752 | new_pkey.flags = GNUNET_NAMESTORE_RF_AUTHORITY | ||
753 | | GNUNET_NAMESTORE_RF_PRIVATE | ||
754 | | GNUNET_NAMESTORE_RF_PENDING; | ||
755 | gph->namestore_task | ||
756 | = GNUNET_NAMESTORE_records_store (namestore_handle, | ||
757 | &gph->shorten_zone_key, | ||
758 | gph->current_label, | ||
759 | 1, &new_pkey, | ||
760 | &create_pkey_cont, gph); | ||
761 | } | ||
762 | |||
763 | |||
764 | /** | ||
765 | * Process result of a DHT lookup for a PSEU record. | ||
766 | * | ||
767 | * @param gph the handle to our shorten operation | ||
768 | * @param pseu the pseu result or NULL | ||
769 | */ | ||
770 | static void | ||
771 | process_pseu_result (struct GetPseuAuthorityHandle* gph, | ||
772 | const char *pseu) | ||
773 | { | ||
774 | if (NULL == pseu) | ||
775 | { | ||
776 | /* no PSEU found, try original label */ | ||
777 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
778 | "No PSEU found, trying original label `%s' instead.\n", | ||
779 | gph->label); | ||
780 | perform_pseu_lookup (gph, gph->label); | ||
781 | return; | ||
782 | } | ||
783 | /* check if 'pseu' is taken */ | ||
784 | perform_pseu_lookup (gph, pseu); | ||
785 | } | ||
786 | |||
787 | |||
788 | /** | ||
789 | * Handle timeout for DHT request during shortening. | ||
790 | * | ||
791 | * @param cls the request handle as closure | ||
792 | * @param tc the task context | ||
793 | */ | ||
794 | static void | ||
795 | handle_auth_discovery_timeout (void *cls, | ||
796 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
797 | { | ||
798 | struct GetPseuAuthorityHandle *gph = cls; | ||
799 | |||
800 | gph->timeout_task = GNUNET_SCHEDULER_NO_TASK; | ||
801 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
802 | "DHT lookup for PSEU query timed out.\n"); | ||
803 | GNUNET_DHT_get_stop (gph->get_handle); | ||
804 | gph->get_handle = NULL; | ||
805 | process_pseu_result (gph, NULL); | ||
806 | } | ||
807 | |||
808 | |||
809 | /** | ||
810 | * Handle decrypted records from DHT result. | ||
811 | * | ||
812 | * @param cls closure with our 'struct GetPseuAuthorityHandle' | ||
813 | * @param rd_count number of entries in 'rd' array | ||
814 | * @param rd array of records with data to store | ||
815 | */ | ||
816 | static void | ||
817 | process_auth_records (void *cls, | ||
818 | unsigned int rd_count, | ||
819 | const struct GNUNET_NAMESTORE_RecordData *rd) | ||
820 | { | ||
821 | struct GetPseuAuthorityHandle *gph = cls; | ||
822 | unsigned int i; | ||
823 | |||
824 | for (i=0; i < rd_count; i++) | ||
825 | { | ||
826 | if (GNUNET_NAMESTORE_TYPE_PSEU == rd[i].record_type) | ||
827 | { | ||
828 | /* found pseu */ | ||
829 | process_pseu_result (gph, | ||
830 | (const char *) rd[i].data); | ||
831 | return; | ||
832 | } | ||
833 | } | ||
834 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
835 | "No PSEU record found in DHT reply.\n"); | ||
836 | process_pseu_result (gph, NULL); | ||
837 | } | ||
838 | |||
839 | |||
840 | /** | ||
841 | * Function called when we find a PSEU entry in the DHT | ||
842 | * | ||
843 | * @param cls the request handle | ||
844 | * @param exp lifetime | ||
845 | * @param key the key the record was stored under | ||
846 | * @param get_path get path | ||
847 | * @param get_path_length get path length | ||
848 | * @param put_path put path | ||
849 | * @param put_path_length put path length | ||
850 | * @param type the block type | ||
851 | * @param size the size of the record | ||
852 | * @param data the record data | ||
853 | */ | ||
854 | static void | ||
855 | process_auth_discovery_dht_result (void* cls, | ||
856 | struct GNUNET_TIME_Absolute exp, | ||
857 | const struct GNUNET_HashCode *key, | ||
858 | const struct GNUNET_PeerIdentity *get_path, | ||
859 | unsigned int get_path_length, | ||
860 | const struct GNUNET_PeerIdentity *put_path, | ||
861 | unsigned int put_path_length, | ||
862 | enum GNUNET_BLOCK_Type type, | ||
863 | size_t size, | ||
864 | const void *data) | ||
865 | { | ||
866 | struct GetPseuAuthorityHandle *gph = cls; | ||
867 | const struct GNUNET_NAMESTORE_Block *block; | ||
868 | |||
869 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
870 | "Got DHT result for PSEU request\n"); | ||
871 | GNUNET_DHT_get_stop (gph->get_handle); | ||
872 | gph->get_handle = NULL; | ||
873 | GNUNET_SCHEDULER_cancel (gph->timeout_task); | ||
874 | gph->timeout_task = GNUNET_SCHEDULER_NO_TASK; | ||
875 | |||
876 | if (NULL == data) | ||
877 | { | ||
878 | /* is this allowed!? */ | ||
879 | GNUNET_break (0); | ||
880 | process_pseu_result (gph, NULL); | ||
881 | return; | ||
882 | } | ||
883 | if (size < sizeof (struct GNUNET_NAMESTORE_Block)) | ||
884 | { | ||
885 | /* how did this pass DHT block validation!? */ | ||
886 | GNUNET_break (0); | ||
887 | process_pseu_result (gph, NULL); | ||
888 | return; | ||
889 | } | ||
890 | block = data; | ||
891 | if (size != | ||
892 | ntohs (block->purpose.size) + | ||
893 | sizeof (struct GNUNET_CRYPTO_EccPublicKey) + | ||
894 | sizeof (struct GNUNET_CRYPTO_EccSignature)) | ||
895 | { | ||
896 | /* how did this pass DHT block validation!? */ | ||
897 | GNUNET_break (0); | ||
898 | process_pseu_result (gph, NULL); | ||
899 | return; | ||
900 | } | ||
901 | if (GNUNET_OK != | ||
902 | GNUNET_NAMESTORE_block_decrypt (block, | ||
903 | &gph->target_zone, | ||
904 | GNUNET_GNS_TLD_PLUS, | ||
905 | &process_auth_records, | ||
906 | gph)) | ||
907 | { | ||
908 | /* other peer encrypted invalid block, complain */ | ||
909 | GNUNET_break_op (0); | ||
910 | process_pseu_result (gph, NULL); | ||
911 | return; | ||
912 | } | ||
913 | } | ||
914 | |||
915 | |||
916 | /** | ||
917 | * Callback called by namestore for a zone to name result. We're | ||
918 | * trying to see if a short name for a given zone already exists. | ||
919 | * | ||
920 | * @param cls the closure | ||
921 | * @param zone_key the zone we queried | ||
922 | * @param name the name found or NULL | ||
923 | * @param rd_len number of records for the name | ||
924 | * @param rd the record data (PKEY) for the name | ||
925 | */ | ||
926 | static void | ||
927 | process_zone_to_name_discover (void *cls, | ||
928 | const struct GNUNET_CRYPTO_EccPrivateKey *zone_key, | ||
929 | const char *name, | ||
930 | unsigned int rd_len, | ||
931 | const struct GNUNET_NAMESTORE_RecordData *rd) | ||
932 | { | ||
933 | struct GetPseuAuthorityHandle* gph = cls; | ||
934 | struct GNUNET_HashCode lookup_key; | ||
935 | |||
936 | gph->namestore_task = NULL; | ||
937 | if (0 != rd_len) | ||
938 | { | ||
939 | /* we found a match in our own zone */ | ||
940 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
941 | "Shortening aborted, name `%s' already reserved for the zone\n", | ||
942 | name); | ||
943 | free_get_pseu_authority_handle (gph); | ||
944 | return; | ||
945 | } | ||
946 | /* record does not yet exist, go into DHT to find PSEU record */ | ||
947 | GNUNET_NAMESTORE_query_from_public_key (&gph->target_zone, | ||
948 | GNUNET_GNS_TLD_PLUS, | ||
949 | &lookup_key); | ||
950 | gph->timeout_task = GNUNET_SCHEDULER_add_delayed (DHT_LOOKUP_TIMEOUT, | ||
951 | &handle_auth_discovery_timeout, | ||
952 | gph); | ||
953 | gph->get_handle = GNUNET_DHT_get_start (dht_handle, | ||
954 | GNUNET_BLOCK_TYPE_GNS_NAMERECORD, | ||
955 | &lookup_key, | ||
956 | DHT_GNS_REPLICATION_LEVEL, | ||
957 | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, | ||
958 | NULL, 0, | ||
959 | &process_auth_discovery_dht_result, | ||
960 | gph); | ||
961 | } | ||
962 | |||
963 | |||
964 | /** | ||
965 | * Start shortening algorithm, try to allocate a nice short | ||
966 | * canonical name for @a pub in @a shorten_zone, using | ||
967 | * @a original_label as one possible suggestion. | ||
968 | * | ||
969 | * @param original_label original label for the zone | ||
970 | * @param pub public key of the zone to shorten | ||
971 | * @param shorten_zone private key of the target zone for the new record | ||
972 | */ | ||
973 | static void | ||
974 | start_shorten (const char *original_label, | ||
975 | const struct GNUNET_CRYPTO_EccPublicKey *pub, | ||
976 | const struct GNUNET_CRYPTO_EccPrivateKey *shorten_zone) | ||
977 | { | ||
978 | struct GetPseuAuthorityHandle *gph; | ||
979 | |||
980 | if (strlen (original_label) > GNUNET_DNSPARSER_MAX_LABEL_LENGTH) | ||
981 | { | ||
982 | GNUNET_break (0); | ||
983 | return; | ||
984 | } | ||
985 | gph = GNUNET_new (struct GetPseuAuthorityHandle); | ||
986 | gph->shorten_zone_key = *shorten_zone; | ||
987 | gph->target_zone = *pub; | ||
988 | strcpy (gph->label, original_label); | ||
989 | GNUNET_CONTAINER_DLL_insert (gph_head, gph_tail, gph); | ||
990 | /* first, check if we *already* have a record for this zone */ | ||
991 | gph->namestore_task = GNUNET_NAMESTORE_zone_to_name (namestore_handle, | ||
992 | shorten_zone, | ||
993 | pub, | ||
994 | &process_zone_to_name_discover, | ||
995 | gph); | ||
996 | } | ||
997 | |||
998 | 468 | ||
999 | /* ************************** Resolution **************************** */ | 469 | /* ************************** Resolution **************************** */ |
1000 | 470 | ||
@@ -2394,15 +1864,14 @@ GNS_resolver_done () | |||
2394 | rh->proc (rh->proc_cls, 0, NULL); | 1864 | rh->proc (rh->proc_cls, 0, NULL); |
2395 | GNS_resolver_lookup_cancel (rh); | 1865 | GNS_resolver_lookup_cancel (rh); |
2396 | } | 1866 | } |
2397 | /* abort active shorten operations */ | ||
2398 | while (NULL != gph_head) | ||
2399 | free_get_pseu_authority_handle (gph_head); | ||
2400 | GNUNET_CONTAINER_heap_destroy (dht_lookup_heap); | 1867 | GNUNET_CONTAINER_heap_destroy (dht_lookup_heap); |
2401 | dht_lookup_heap = NULL; | 1868 | dht_lookup_heap = NULL; |
2402 | GNUNET_DNSSTUB_stop (dns_handle); | 1869 | GNUNET_DNSSTUB_stop (dns_handle); |
2403 | dns_handle = NULL; | 1870 | dns_handle = NULL; |
2404 | GNUNET_VPN_disconnect (vpn_handle); | 1871 | GNUNET_VPN_disconnect (vpn_handle); |
2405 | vpn_handle = NULL; | 1872 | vpn_handle = NULL; |
1873 | dht_handle = NULL; | ||
1874 | namestore_handle = NULL; | ||
2406 | } | 1875 | } |
2407 | 1876 | ||
2408 | 1877 | ||
diff --git a/src/gns/gnunet-service-gns_shorten.c b/src/gns/gnunet-service-gns_shorten.c new file mode 100644 index 000000000..6f27a7234 --- /dev/null +++ b/src/gns/gnunet-service-gns_shorten.c | |||
@@ -0,0 +1,568 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2011-2013 Christian Grothoff (and other contributing authors) | ||
4 | |||
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 | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file gns/gnunet-service-gns_shorten.c | ||
23 | * @brief GNUnet GNS shortening logic | ||
24 | * @author Martin Schanzenbach | ||
25 | * @author Christian Grothoff | ||
26 | */ | ||
27 | #include "platform.h" | ||
28 | #include "gnunet_util_lib.h" | ||
29 | #include "gnunet_dht_service.h" | ||
30 | #include "gnunet_namestore_service.h" | ||
31 | #include "gnunet_resolver_service.h" | ||
32 | #include "gnunet_gns_service.h" | ||
33 | #include "gns.h" | ||
34 | #include "gnunet-service-gns_shorten.h" | ||
35 | #include "gnunet_vpn_service.h" | ||
36 | |||
37 | |||
38 | /** | ||
39 | * Default DHT timeout for lookups. | ||
40 | */ | ||
41 | #define DHT_LOOKUP_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60) | ||
42 | |||
43 | /** | ||
44 | * DHT replication level | ||
45 | */ | ||
46 | #define DHT_GNS_REPLICATION_LEVEL 5 | ||
47 | |||
48 | |||
49 | /** | ||
50 | * Handle for a PSEU lookup used to shorten names. | ||
51 | */ | ||
52 | struct GetPseuAuthorityHandle | ||
53 | { | ||
54 | /** | ||
55 | * DLL | ||
56 | */ | ||
57 | struct GetPseuAuthorityHandle *next; | ||
58 | |||
59 | /** | ||
60 | * DLL | ||
61 | */ | ||
62 | struct GetPseuAuthorityHandle *prev; | ||
63 | |||
64 | /** | ||
65 | * Private key of the (shorten) zone to store the resulting | ||
66 | * pseudonym in. | ||
67 | */ | ||
68 | struct GNUNET_CRYPTO_EccPrivateKey shorten_zone_key; | ||
69 | |||
70 | /** | ||
71 | * Original label (used if no PSEU record is found). | ||
72 | */ | ||
73 | char label[GNUNET_DNSPARSER_MAX_LABEL_LENGTH + 1]; | ||
74 | |||
75 | /** | ||
76 | * Label we are currently trying out (during #perform_pseu_lookup). | ||
77 | */ | ||
78 | char *current_label; | ||
79 | |||
80 | /** | ||
81 | * The zone for which we are trying to find the PSEU record. | ||
82 | */ | ||
83 | struct GNUNET_CRYPTO_EccPublicKey target_zone; | ||
84 | |||
85 | /** | ||
86 | * Handle for DHT lookups. Should be NULL if no lookups are in progress | ||
87 | */ | ||
88 | struct GNUNET_DHT_GetHandle *get_handle; | ||
89 | |||
90 | /** | ||
91 | * Handle to namestore request | ||
92 | */ | ||
93 | struct GNUNET_NAMESTORE_QueueEntry *namestore_task; | ||
94 | |||
95 | /** | ||
96 | * Task to abort DHT lookup operation. | ||
97 | */ | ||
98 | GNUNET_SCHEDULER_TaskIdentifier timeout_task; | ||
99 | |||
100 | }; | ||
101 | |||
102 | |||
103 | /** | ||
104 | * Head of PSEU/shorten operations list. | ||
105 | */ | ||
106 | static struct GetPseuAuthorityHandle *gph_head; | ||
107 | |||
108 | /** | ||
109 | * Tail of PSEU/shorten operations list. | ||
110 | */ | ||
111 | static struct GetPseuAuthorityHandle *gph_tail; | ||
112 | |||
113 | /** | ||
114 | * Our handle to the namestore service | ||
115 | */ | ||
116 | static struct GNUNET_NAMESTORE_Handle *namestore_handle; | ||
117 | |||
118 | /** | ||
119 | * Resolver handle to the dht | ||
120 | */ | ||
121 | static struct GNUNET_DHT_Handle *dht_handle; | ||
122 | |||
123 | /** | ||
124 | * Cleanup a 'struct GetPseuAuthorityHandle', terminating all | ||
125 | * pending activities. | ||
126 | * | ||
127 | * @param gph handle to terminate | ||
128 | */ | ||
129 | static void | ||
130 | free_get_pseu_authority_handle (struct GetPseuAuthorityHandle *gph) | ||
131 | { | ||
132 | if (NULL != gph->get_handle) | ||
133 | { | ||
134 | GNUNET_DHT_get_stop (gph->get_handle); | ||
135 | gph->get_handle = NULL; | ||
136 | } | ||
137 | if (NULL != gph->namestore_task) | ||
138 | { | ||
139 | GNUNET_NAMESTORE_cancel (gph->namestore_task); | ||
140 | gph->namestore_task = NULL; | ||
141 | } | ||
142 | if (GNUNET_SCHEDULER_NO_TASK != gph->timeout_task) | ||
143 | { | ||
144 | GNUNET_SCHEDULER_cancel (gph->timeout_task); | ||
145 | gph->timeout_task = GNUNET_SCHEDULER_NO_TASK; | ||
146 | } | ||
147 | GNUNET_CONTAINER_DLL_remove (gph_head, gph_tail, gph); | ||
148 | GNUNET_free_non_null (gph->current_label); | ||
149 | GNUNET_free (gph); | ||
150 | } | ||
151 | |||
152 | |||
153 | /** | ||
154 | * Continuation for pkey record creation (shorten) | ||
155 | * | ||
156 | * @param cls a GetPseuAuthorityHandle | ||
157 | * @param success unused | ||
158 | * @param emsg unused | ||
159 | */ | ||
160 | static void | ||
161 | create_pkey_cont (void* cls, | ||
162 | int32_t success, | ||
163 | const char *emsg) | ||
164 | { | ||
165 | struct GetPseuAuthorityHandle* gph = cls; | ||
166 | |||
167 | gph->namestore_task = NULL; | ||
168 | free_get_pseu_authority_handle (gph); | ||
169 | } | ||
170 | |||
171 | |||
172 | /** | ||
173 | * Namestore calls this function if we have record for this name. | ||
174 | * (or with rd_count=0 to indicate no matches). | ||
175 | * | ||
176 | * @param cls the pending query | ||
177 | * @param rd_count the number of records with 'name' | ||
178 | * @param rd the record data | ||
179 | */ | ||
180 | static void | ||
181 | process_pseu_lookup_ns (void *cls, | ||
182 | unsigned int rd_count, | ||
183 | const struct GNUNET_NAMESTORE_RecordData *rd); | ||
184 | |||
185 | |||
186 | /** | ||
187 | * We obtained a result for our query to the shorten zone from | ||
188 | * the namestore. Try to decrypt. | ||
189 | * | ||
190 | * @param cls the handle to our shorten operation | ||
191 | * @param block resulting encrypted block | ||
192 | */ | ||
193 | static void | ||
194 | process_pseu_block_ns (void *cls, | ||
195 | const struct GNUNET_NAMESTORE_Block *block) | ||
196 | { | ||
197 | struct GetPseuAuthorityHandle *gph = cls; | ||
198 | struct GNUNET_CRYPTO_EccPublicKey pub; | ||
199 | |||
200 | gph->namestore_task = NULL; | ||
201 | if (NULL == block) | ||
202 | { | ||
203 | process_pseu_lookup_ns (gph, 0, NULL); | ||
204 | return; | ||
205 | } | ||
206 | GNUNET_CRYPTO_ecc_key_get_public (&gph->shorten_zone_key, | ||
207 | &pub); | ||
208 | if (GNUNET_OK != | ||
209 | GNUNET_NAMESTORE_block_decrypt (block, | ||
210 | &pub, | ||
211 | gph->current_label, | ||
212 | &process_pseu_lookup_ns, | ||
213 | gph)) | ||
214 | { | ||
215 | GNUNET_break (0); | ||
216 | free_get_pseu_authority_handle (gph); | ||
217 | return; | ||
218 | } | ||
219 | } | ||
220 | |||
221 | |||
222 | /** | ||
223 | * Lookup in the namestore for the shorten zone the given label. | ||
224 | * | ||
225 | * @param gph the handle to our shorten operation | ||
226 | * @param label the label to lookup | ||
227 | */ | ||
228 | static void | ||
229 | perform_pseu_lookup (struct GetPseuAuthorityHandle *gph, | ||
230 | const char *label) | ||
231 | { | ||
232 | struct GNUNET_CRYPTO_EccPublicKey pub; | ||
233 | struct GNUNET_HashCode query; | ||
234 | |||
235 | GNUNET_CRYPTO_ecc_key_get_public (&gph->shorten_zone_key, | ||
236 | &pub); | ||
237 | GNUNET_free_non_null (gph->current_label); | ||
238 | gph->current_label = GNUNET_strdup (label); | ||
239 | GNUNET_NAMESTORE_query_from_public_key (&pub, | ||
240 | label, | ||
241 | &query); | ||
242 | gph->namestore_task = GNUNET_NAMESTORE_lookup_block (namestore_handle, | ||
243 | &query, | ||
244 | &process_pseu_block_ns, | ||
245 | gph); | ||
246 | } | ||
247 | |||
248 | |||
249 | /** | ||
250 | * Namestore calls this function if we have record for this name. | ||
251 | * (or with rd_count=0 to indicate no matches). | ||
252 | * | ||
253 | * @param cls the pending query | ||
254 | * @param rd_count the number of records with 'name' | ||
255 | * @param rd the record data | ||
256 | */ | ||
257 | static void | ||
258 | process_pseu_lookup_ns (void *cls, | ||
259 | unsigned int rd_count, | ||
260 | const struct GNUNET_NAMESTORE_RecordData *rd) | ||
261 | { | ||
262 | struct GetPseuAuthorityHandle *gph = cls; | ||
263 | struct GNUNET_NAMESTORE_RecordData new_pkey; | ||
264 | |||
265 | gph->namestore_task = NULL; | ||
266 | if (rd_count > 0) | ||
267 | { | ||
268 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
269 | "Name `%s' already taken, cannot shorten.\n", | ||
270 | gph->current_label); | ||
271 | /* if this was not yet the original label, try one more | ||
272 | time, this time not using PSEU but the original label */ | ||
273 | if (0 == strcmp (gph->current_label, | ||
274 | gph->label)) | ||
275 | { | ||
276 | free_get_pseu_authority_handle (gph); | ||
277 | } | ||
278 | else | ||
279 | { | ||
280 | perform_pseu_lookup (gph, gph->label); | ||
281 | } | ||
282 | return; | ||
283 | } | ||
284 | /* name is available */ | ||
285 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
286 | "Shortening `%s' to `%s'\n", | ||
287 | GNUNET_NAMESTORE_z2s (&gph->target_zone), | ||
288 | gph->current_label); | ||
289 | new_pkey.expiration_time = UINT64_MAX; | ||
290 | new_pkey.data_size = sizeof (struct GNUNET_CRYPTO_EccPublicKey); | ||
291 | new_pkey.data = &gph->target_zone; | ||
292 | new_pkey.record_type = GNUNET_NAMESTORE_TYPE_PKEY; | ||
293 | new_pkey.flags = GNUNET_NAMESTORE_RF_AUTHORITY | ||
294 | | GNUNET_NAMESTORE_RF_PRIVATE | ||
295 | | GNUNET_NAMESTORE_RF_PENDING; | ||
296 | gph->namestore_task | ||
297 | = GNUNET_NAMESTORE_records_store (namestore_handle, | ||
298 | &gph->shorten_zone_key, | ||
299 | gph->current_label, | ||
300 | 1, &new_pkey, | ||
301 | &create_pkey_cont, gph); | ||
302 | } | ||
303 | |||
304 | |||
305 | /** | ||
306 | * Process result of a DHT lookup for a PSEU record. | ||
307 | * | ||
308 | * @param gph the handle to our shorten operation | ||
309 | * @param pseu the pseu result or NULL | ||
310 | */ | ||
311 | static void | ||
312 | process_pseu_result (struct GetPseuAuthorityHandle* gph, | ||
313 | const char *pseu) | ||
314 | { | ||
315 | if (NULL == pseu) | ||
316 | { | ||
317 | /* no PSEU found, try original label */ | ||
318 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
319 | "No PSEU found, trying original label `%s' instead.\n", | ||
320 | gph->label); | ||
321 | perform_pseu_lookup (gph, gph->label); | ||
322 | return; | ||
323 | } | ||
324 | /* check if 'pseu' is taken */ | ||
325 | perform_pseu_lookup (gph, pseu); | ||
326 | } | ||
327 | |||
328 | |||
329 | /** | ||
330 | * Handle timeout for DHT request during shortening. | ||
331 | * | ||
332 | * @param cls the request handle as closure | ||
333 | * @param tc the task context | ||
334 | */ | ||
335 | static void | ||
336 | handle_auth_discovery_timeout (void *cls, | ||
337 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
338 | { | ||
339 | struct GetPseuAuthorityHandle *gph = cls; | ||
340 | |||
341 | gph->timeout_task = GNUNET_SCHEDULER_NO_TASK; | ||
342 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
343 | "DHT lookup for PSEU query timed out.\n"); | ||
344 | GNUNET_DHT_get_stop (gph->get_handle); | ||
345 | gph->get_handle = NULL; | ||
346 | process_pseu_result (gph, NULL); | ||
347 | } | ||
348 | |||
349 | |||
350 | /** | ||
351 | * Handle decrypted records from DHT result. | ||
352 | * | ||
353 | * @param cls closure with our 'struct GetPseuAuthorityHandle' | ||
354 | * @param rd_count number of entries in 'rd' array | ||
355 | * @param rd array of records with data to store | ||
356 | */ | ||
357 | static void | ||
358 | process_auth_records (void *cls, | ||
359 | unsigned int rd_count, | ||
360 | const struct GNUNET_NAMESTORE_RecordData *rd) | ||
361 | { | ||
362 | struct GetPseuAuthorityHandle *gph = cls; | ||
363 | unsigned int i; | ||
364 | |||
365 | for (i=0; i < rd_count; i++) | ||
366 | { | ||
367 | if (GNUNET_NAMESTORE_TYPE_PSEU == rd[i].record_type) | ||
368 | { | ||
369 | /* found pseu */ | ||
370 | process_pseu_result (gph, | ||
371 | (const char *) rd[i].data); | ||
372 | return; | ||
373 | } | ||
374 | } | ||
375 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
376 | "No PSEU record found in DHT reply.\n"); | ||
377 | process_pseu_result (gph, NULL); | ||
378 | } | ||
379 | |||
380 | |||
381 | /** | ||
382 | * Function called when we find a PSEU entry in the DHT | ||
383 | * | ||
384 | * @param cls the request handle | ||
385 | * @param exp lifetime | ||
386 | * @param key the key the record was stored under | ||
387 | * @param get_path get path | ||
388 | * @param get_path_length get path length | ||
389 | * @param put_path put path | ||
390 | * @param put_path_length put path length | ||
391 | * @param type the block type | ||
392 | * @param size the size of the record | ||
393 | * @param data the record data | ||
394 | */ | ||
395 | static void | ||
396 | process_auth_discovery_dht_result (void* cls, | ||
397 | struct GNUNET_TIME_Absolute exp, | ||
398 | const struct GNUNET_HashCode *key, | ||
399 | const struct GNUNET_PeerIdentity *get_path, | ||
400 | unsigned int get_path_length, | ||
401 | const struct GNUNET_PeerIdentity *put_path, | ||
402 | unsigned int put_path_length, | ||
403 | enum GNUNET_BLOCK_Type type, | ||
404 | size_t size, | ||
405 | const void *data) | ||
406 | { | ||
407 | struct GetPseuAuthorityHandle *gph = cls; | ||
408 | const struct GNUNET_NAMESTORE_Block *block; | ||
409 | |||
410 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
411 | "Got DHT result for PSEU request\n"); | ||
412 | GNUNET_DHT_get_stop (gph->get_handle); | ||
413 | gph->get_handle = NULL; | ||
414 | GNUNET_SCHEDULER_cancel (gph->timeout_task); | ||
415 | gph->timeout_task = GNUNET_SCHEDULER_NO_TASK; | ||
416 | |||
417 | if (NULL == data) | ||
418 | { | ||
419 | /* is this allowed!? */ | ||
420 | GNUNET_break (0); | ||
421 | process_pseu_result (gph, NULL); | ||
422 | return; | ||
423 | } | ||
424 | if (size < sizeof (struct GNUNET_NAMESTORE_Block)) | ||
425 | { | ||
426 | /* how did this pass DHT block validation!? */ | ||
427 | GNUNET_break (0); | ||
428 | process_pseu_result (gph, NULL); | ||
429 | return; | ||
430 | } | ||
431 | block = data; | ||
432 | if (size != | ||
433 | ntohs (block->purpose.size) + | ||
434 | sizeof (struct GNUNET_CRYPTO_EccPublicKey) + | ||
435 | sizeof (struct GNUNET_CRYPTO_EccSignature)) | ||
436 | { | ||
437 | /* how did this pass DHT block validation!? */ | ||
438 | GNUNET_break (0); | ||
439 | process_pseu_result (gph, NULL); | ||
440 | return; | ||
441 | } | ||
442 | if (GNUNET_OK != | ||
443 | GNUNET_NAMESTORE_block_decrypt (block, | ||
444 | &gph->target_zone, | ||
445 | GNUNET_GNS_TLD_PLUS, | ||
446 | &process_auth_records, | ||
447 | gph)) | ||
448 | { | ||
449 | /* other peer encrypted invalid block, complain */ | ||
450 | GNUNET_break_op (0); | ||
451 | process_pseu_result (gph, NULL); | ||
452 | return; | ||
453 | } | ||
454 | } | ||
455 | |||
456 | |||
457 | /** | ||
458 | * Callback called by namestore for a zone to name result. We're | ||
459 | * trying to see if a short name for a given zone already exists. | ||
460 | * | ||
461 | * @param cls the closure | ||
462 | * @param zone_key the zone we queried | ||
463 | * @param name the name found or NULL | ||
464 | * @param rd_len number of records for the name | ||
465 | * @param rd the record data (PKEY) for the name | ||
466 | */ | ||
467 | static void | ||
468 | process_zone_to_name_discover (void *cls, | ||
469 | const struct GNUNET_CRYPTO_EccPrivateKey *zone_key, | ||
470 | const char *name, | ||
471 | unsigned int rd_len, | ||
472 | const struct GNUNET_NAMESTORE_RecordData *rd) | ||
473 | { | ||
474 | struct GetPseuAuthorityHandle* gph = cls; | ||
475 | struct GNUNET_HashCode lookup_key; | ||
476 | |||
477 | gph->namestore_task = NULL; | ||
478 | if (0 != rd_len) | ||
479 | { | ||
480 | /* we found a match in our own zone */ | ||
481 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
482 | "Shortening aborted, name `%s' already reserved for the zone\n", | ||
483 | name); | ||
484 | free_get_pseu_authority_handle (gph); | ||
485 | return; | ||
486 | } | ||
487 | /* record does not yet exist, go into DHT to find PSEU record */ | ||
488 | GNUNET_NAMESTORE_query_from_public_key (&gph->target_zone, | ||
489 | GNUNET_GNS_TLD_PLUS, | ||
490 | &lookup_key); | ||
491 | gph->timeout_task = GNUNET_SCHEDULER_add_delayed (DHT_LOOKUP_TIMEOUT, | ||
492 | &handle_auth_discovery_timeout, | ||
493 | gph); | ||
494 | gph->get_handle = GNUNET_DHT_get_start (dht_handle, | ||
495 | GNUNET_BLOCK_TYPE_GNS_NAMERECORD, | ||
496 | &lookup_key, | ||
497 | DHT_GNS_REPLICATION_LEVEL, | ||
498 | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, | ||
499 | NULL, 0, | ||
500 | &process_auth_discovery_dht_result, | ||
501 | gph); | ||
502 | } | ||
503 | |||
504 | |||
505 | /** | ||
506 | * Start shortening algorithm, try to allocate a nice short | ||
507 | * canonical name for @a pub in @a shorten_zone, using | ||
508 | * @a original_label as one possible suggestion. | ||
509 | * | ||
510 | * @param original_label original label for the zone | ||
511 | * @param pub public key of the zone to shorten | ||
512 | * @param shorten_zone private key of the target zone for the new record | ||
513 | */ | ||
514 | void | ||
515 | GNS_shorten_start (const char *original_label, | ||
516 | const struct GNUNET_CRYPTO_EccPublicKey *pub, | ||
517 | const struct GNUNET_CRYPTO_EccPrivateKey *shorten_zone) | ||
518 | { | ||
519 | struct GetPseuAuthorityHandle *gph; | ||
520 | |||
521 | if (strlen (original_label) > GNUNET_DNSPARSER_MAX_LABEL_LENGTH) | ||
522 | { | ||
523 | GNUNET_break (0); | ||
524 | return; | ||
525 | } | ||
526 | gph = GNUNET_new (struct GetPseuAuthorityHandle); | ||
527 | gph->shorten_zone_key = *shorten_zone; | ||
528 | gph->target_zone = *pub; | ||
529 | strcpy (gph->label, original_label); | ||
530 | GNUNET_CONTAINER_DLL_insert (gph_head, gph_tail, gph); | ||
531 | /* first, check if we *already* have a record for this zone */ | ||
532 | gph->namestore_task = GNUNET_NAMESTORE_zone_to_name (namestore_handle, | ||
533 | shorten_zone, | ||
534 | pub, | ||
535 | &process_zone_to_name_discover, | ||
536 | gph); | ||
537 | } | ||
538 | |||
539 | |||
540 | /** | ||
541 | * Initialize the shortening subsystem | ||
542 | * | ||
543 | * @param nh the namestore handle | ||
544 | * @param dht the dht handle | ||
545 | */ | ||
546 | void | ||
547 | GNS_shorten_init (struct GNUNET_NAMESTORE_Handle *nh, | ||
548 | struct GNUNET_DHT_Handle *dht) | ||
549 | { | ||
550 | namestore_handle = nh; | ||
551 | dht_handle = dht; | ||
552 | } | ||
553 | |||
554 | |||
555 | /** | ||
556 | * Shutdown shortening. | ||
557 | */ | ||
558 | void | ||
559 | GNS_shorten_done () | ||
560 | { | ||
561 | /* abort active shorten operations */ | ||
562 | while (NULL != gph_head) | ||
563 | free_get_pseu_authority_handle (gph_head); | ||
564 | dht_handle = NULL; | ||
565 | namestore_handle = NULL; | ||
566 | } | ||
567 | |||
568 | /* end of gnunet-service-gns_shorten.c */ | ||
diff --git a/src/gns/gnunet-service-gns_shorten.h b/src/gns/gnunet-service-gns_shorten.h new file mode 100644 index 000000000..d71100a88 --- /dev/null +++ b/src/gns/gnunet-service-gns_shorten.h | |||
@@ -0,0 +1,66 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2009-2013 Christian Grothoff (and other contributing authors) | ||
4 | |||
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 | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | /** | ||
21 | * @file gns/gnunet-service-gns_shorten.h | ||
22 | * @brief GNUnet GNS shortening API | ||
23 | * @author Martin Schanzenbach | ||
24 | */ | ||
25 | #ifndef GNS_SHORTEN_H | ||
26 | #define GNS_SHORTEN_H | ||
27 | #include "gns.h" | ||
28 | #include "gnunet_dht_service.h" | ||
29 | #include "gnunet_namestore_service.h" | ||
30 | |||
31 | |||
32 | /** | ||
33 | * Initialize the shorten subsystem. | ||
34 | * MUST be called before #GNS_shorten_start. | ||
35 | * | ||
36 | * @param nh handle to the namestore | ||
37 | * @param dht handle to the dht | ||
38 | */ | ||
39 | void | ||
40 | GNS_shorten_init (struct GNUNET_NAMESTORE_Handle *nh, | ||
41 | struct GNUNET_DHT_Handle *dht); | ||
42 | |||
43 | |||
44 | /** | ||
45 | * Cleanup shorten: Terminate pending lookups | ||
46 | */ | ||
47 | void | ||
48 | GNS_shorten_done (void); | ||
49 | |||
50 | |||
51 | /** | ||
52 | * Start shortening algorithm, try to allocate a nice short | ||
53 | * canonical name for @a pub in @a shorten_zone, using | ||
54 | * @a original_label as one possible suggestion. | ||
55 | * | ||
56 | * @param original_label original label for the zone | ||
57 | * @param pub public key of the zone to shorten | ||
58 | * @param shorten_zone private key of the target zone for the new record | ||
59 | */ | ||
60 | void | ||
61 | GNS_shorten_start (const char *original_label, | ||
62 | const struct GNUNET_CRYPTO_EccPublicKey *pub, | ||
63 | const struct GNUNET_CRYPTO_EccPrivateKey *shorten_zone); | ||
64 | |||
65 | |||
66 | #endif | ||