diff options
author | Philipp Tölke <toelke@in.tum.de> | 2011-03-05 11:17:09 +0000 |
---|---|---|
committer | Philipp Tölke <toelke@in.tum.de> | 2011-03-05 11:17:09 +0000 |
commit | e01209d5d6b3873646727662ab8dfee0189d42a6 (patch) | |
tree | ddc781879f336327700ccb0219ba0792dcef97fe | |
parent | 400de3aa78c110aeca65609af3571b1a65eaf4bf (diff) | |
download | gnunet-e01209d5d6b3873646727662ab8dfee0189d42a6.tar.gz gnunet-e01209d5d6b3873646727662ab8dfee0189d42a6.zip |
read the dns-config from the file
-rw-r--r-- | src/include/gnunet_configuration_lib.h | 21 | ||||
-rw-r--r-- | src/util/configuration.c | 19 | ||||
-rw-r--r-- | src/vpn/gnunet-service-dns.c | 261 |
3 files changed, 247 insertions, 54 deletions
diff --git a/src/include/gnunet_configuration_lib.h b/src/include/gnunet_configuration_lib.h index d921cb9ce..87aa8eacc 100644 --- a/src/include/gnunet_configuration_lib.h +++ b/src/include/gnunet_configuration_lib.h | |||
@@ -142,6 +142,16 @@ typedef void (*GNUNET_CONFIGURATION_Iterator)(void *cls, | |||
142 | 142 | ||
143 | 143 | ||
144 | /** | 144 | /** |
145 | * Function to iterate over section. | ||
146 | * | ||
147 | * @param cls closure | ||
148 | * @param section name of the section | ||
149 | */ | ||
150 | typedef void (*GNUNET_CONFIGURATION_Section_Iterator)(void *cls, | ||
151 | const char *section); | ||
152 | |||
153 | |||
154 | /** | ||
145 | * Iterate over all options in the configuration. | 155 | * Iterate over all options in the configuration. |
146 | * | 156 | * |
147 | * @param cfg configuration to inspect | 157 | * @param cfg configuration to inspect |
@@ -154,6 +164,17 @@ void GNUNET_CONFIGURATION_iterate (const struct GNUNET_CONFIGURATION_Handle *cfg | |||
154 | 164 | ||
155 | 165 | ||
156 | /** | 166 | /** |
167 | * Iterate over all sections in the configuration. | ||
168 | * | ||
169 | * @param cfg configuration to inspect | ||
170 | * @param iter function to call on each section | ||
171 | * @param iter_cls closure for iter | ||
172 | */ | ||
173 | void GNUNET_CONFIGURATION_iterate_sections (const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
174 | GNUNET_CONFIGURATION_Section_Iterator iter, | ||
175 | void *iter_cls); | ||
176 | |||
177 | /** | ||
157 | * Get a configuration value that should be a number. | 178 | * Get a configuration value that should be a number. |
158 | * | 179 | * |
159 | * @param cfg configuration to inspect | 180 | * @param cfg configuration to inspect |
diff --git a/src/util/configuration.c b/src/util/configuration.c index 07d8cb941..10f2d7575 100644 --- a/src/util/configuration.c +++ b/src/util/configuration.c | |||
@@ -402,6 +402,25 @@ GNUNET_CONFIGURATION_iterate (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
402 | 402 | ||
403 | 403 | ||
404 | /** | 404 | /** |
405 | * Iterate over all sections in the configuration. | ||
406 | * | ||
407 | * @param cfg configuration to inspect | ||
408 | * @param iter function to call on each section | ||
409 | * @param iter_cls closure for iter | ||
410 | */ | ||
411 | void | ||
412 | GNUNET_CONFIGURATION_iterate_sections (const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
413 | GNUNET_CONFIGURATION_Section_Iterator iter, | ||
414 | void *iter_cls) | ||
415 | { | ||
416 | struct ConfigSection *spos; | ||
417 | |||
418 | for (spos = cfg->sections; spos != NULL; spos = spos->next) | ||
419 | iter (iter_cls, spos->name); | ||
420 | } | ||
421 | |||
422 | |||
423 | /** | ||
405 | * Copy a configuration value to the given target configuration. | 424 | * Copy a configuration value to the given target configuration. |
406 | * Overwrites existing entries. | 425 | * Overwrites existing entries. |
407 | * | 426 | * |
diff --git a/src/vpn/gnunet-service-dns.c b/src/vpn/gnunet-service-dns.c index ab13f1ef8..a9d938372 100644 --- a/src/vpn/gnunet-service-dns.c +++ b/src/vpn/gnunet-service-dns.c | |||
@@ -61,6 +61,11 @@ static struct GNUNET_DHT_Handle *dht; | |||
61 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | 61 | static const struct GNUNET_CONFIGURATION_Handle *cfg; |
62 | 62 | ||
63 | /** | 63 | /** |
64 | * The handle to the service-configuration | ||
65 | */ | ||
66 | static struct GNUNET_CONFIGURATION_Handle *servicecfg; | ||
67 | |||
68 | /** | ||
64 | * A list of DNS-Responses that have to be sent to the requesting client | 69 | * A list of DNS-Responses that have to be sent to the requesting client |
65 | */ | 70 | */ |
66 | static struct answer_packet_list *head; | 71 | static struct answer_packet_list *head; |
@@ -568,74 +573,222 @@ cleanup_task (void *cls, | |||
568 | } | 573 | } |
569 | 574 | ||
570 | /** | 575 | /** |
571 | * Publish a DNS-record in the DHT. This is up to now just for testing. | 576 | * @brief Create a port-map from udp and tcp redirects |
577 | * | ||
578 | * @param udp_redirects | ||
579 | * @param tcp_redirects | ||
580 | * | ||
581 | * @return | ||
572 | */ | 582 | */ |
573 | static void | 583 | uint64_t |
574 | publish_name (void *cls, | 584 | get_port_from_redirects (const char *udp_redirects, const char *tcp_redirects) |
575 | const struct GNUNET_SCHEDULER_TaskContext *tc) { | 585 | { |
576 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | 586 | uint64_t ret = 0; |
577 | return; | 587 | char* cpy, *hostname, *redirect; |
588 | int local_port, count = 0; | ||
578 | 589 | ||
579 | char* name = "philipptoelke.gnunet."; | 590 | if (NULL != udp_redirects) |
580 | size_t size = sizeof(struct GNUNET_DNS_Record); | 591 | { |
581 | struct GNUNET_DNS_Record data; | 592 | cpy = GNUNET_strdup (udp_redirects); |
582 | memset(&data, 0, size); | 593 | for (redirect = strtok (cpy, " "); redirect != NULL; redirect = strtok (NULL, " ")) |
594 | { | ||
595 | if (NULL == (hostname = strstr (redirect, ":"))) | ||
596 | { | ||
597 | // FIXME: bitch | ||
598 | continue; | ||
599 | } | ||
600 | hostname[0] = '\0'; | ||
601 | local_port = atoi (redirect); | ||
602 | GNUNET_assert ((local_port > 0) && (local_port < 65536)); // FIXME: don't crash!!! | ||
603 | |||
604 | ret |= (0xFFFF & htons(local_port)); | ||
605 | ret <<= 16; | ||
606 | count ++; | ||
607 | |||
608 | if(count > 4) | ||
609 | { | ||
610 | ret = 0; | ||
611 | goto out; | ||
612 | } | ||
613 | } | ||
614 | GNUNET_free(cpy); | ||
615 | cpy = NULL; | ||
616 | } | ||
583 | 617 | ||
584 | data.purpose.size = htonl(size - sizeof(struct GNUNET_CRYPTO_RsaSignature)); | 618 | if (NULL != tcp_redirects) |
585 | data.purpose.purpose = GNUNET_SIGNATURE_PURPOSE_DNS_RECORD; | 619 | { |
620 | cpy = GNUNET_strdup (tcp_redirects); | ||
621 | for (redirect = strtok (cpy, " "); redirect != NULL; redirect = strtok (NULL, " ")) | ||
622 | { | ||
623 | if (NULL == (hostname = strstr (redirect, ":"))) | ||
624 | { | ||
625 | // FIXME: bitch | ||
626 | continue; | ||
627 | } | ||
628 | hostname[0] = '\0'; | ||
629 | local_port = atoi (redirect); | ||
630 | GNUNET_assert ((local_port > 0) && (local_port < 65536)); // FIXME: don't crash!!! | ||
631 | |||
632 | ret |= (0xFFFF & htons(local_port)); | ||
633 | ret <<= 16; | ||
634 | count ++; | ||
635 | |||
636 | if(count > 4) | ||
637 | { | ||
638 | ret = 0; | ||
639 | goto out; | ||
640 | } | ||
641 | } | ||
642 | GNUNET_free(cpy); | ||
643 | cpy = NULL; | ||
644 | } | ||
586 | 645 | ||
587 | GNUNET_CRYPTO_hash(name, strlen(name)+1, &data.service_descriptor); | 646 | out: |
588 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Store with key1 %x\n", *((unsigned long long*)&data.service_descriptor)); | 647 | if (NULL != cpy) |
648 | GNUNET_free(cpy); | ||
649 | return ret; | ||
650 | } | ||
589 | 651 | ||
590 | data.service_type = htonl(GNUNET_DNS_SERVICE_TYPE_UDP); | 652 | void |
591 | data.ports = htons(69); | 653 | publish_name (const char *name, uint64_t ports, uint32_t service_type, |
654 | struct GNUNET_CRYPTO_RsaPrivateKey *my_private_key) | ||
655 | { | ||
656 | size_t size = sizeof (struct GNUNET_DNS_Record); | ||
657 | struct GNUNET_DNS_Record data; | ||
658 | memset (&data, 0, size); | ||
592 | 659 | ||
593 | char* keyfile; | 660 | data.purpose.size = |
594 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename(cfg, "GNUNETD", | 661 | htonl (size - sizeof (struct GNUNET_CRYPTO_RsaSignature)); |
595 | "HOSTKEY", &keyfile)) | 662 | data.purpose.purpose = GNUNET_SIGNATURE_PURPOSE_DNS_RECORD; |
596 | { | 663 | |
597 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "could not read keyfile-value\n"); | 664 | GNUNET_CRYPTO_hash (name, strlen (name) + 1, &data.service_descriptor); |
598 | if (keyfile != NULL) GNUNET_free(keyfile); | 665 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Store with key1 %x\n", |
599 | return; | 666 | *((unsigned long long *) &data.service_descriptor)); |
600 | } | ||
601 | 667 | ||
602 | struct GNUNET_CRYPTO_RsaPrivateKey *my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file(keyfile); | 668 | data.service_type = service_type; |
603 | GNUNET_free(keyfile); | 669 | data.ports = ports; |
604 | GNUNET_assert(my_private_key != NULL); | ||
605 | 670 | ||
606 | GNUNET_CRYPTO_rsa_key_get_public(my_private_key, &data.peer); | 671 | GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &data.peer); |
607 | 672 | ||
608 | data.expiration_time = GNUNET_TIME_relative_to_absolute(GNUNET_TIME_UNIT_HOURS); | 673 | data.expiration_time = |
674 | GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_HOURS, 2)); | ||
609 | 675 | ||
610 | /* Sign the block */ | 676 | /* Sign the block */ |
611 | if (GNUNET_OK != GNUNET_CRYPTO_rsa_sign(my_private_key, | 677 | if (GNUNET_OK != GNUNET_CRYPTO_rsa_sign (my_private_key, |
612 | &data.purpose, | 678 | &data.purpose, &data.signature)) |
613 | &data.signature)) | 679 | { |
680 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "could not sign DNS_Record\n"); | ||
681 | return; | ||
682 | } | ||
683 | |||
684 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
685 | "Putting with key %08x, size = %d\n", | ||
686 | *((unsigned int *) &data.service_descriptor), size); | ||
687 | |||
688 | GNUNET_DHT_put (dht, | ||
689 | &data.service_descriptor, | ||
690 | DEFAULT_PUT_REPLICATION, | ||
691 | GNUNET_DHT_RO_NONE, | ||
692 | GNUNET_BLOCK_TYPE_DNS, | ||
693 | size, | ||
694 | (char *) &data, | ||
695 | GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_HOURS), | ||
696 | GNUNET_TIME_UNIT_MINUTES, NULL, NULL); | ||
697 | } | ||
698 | |||
699 | /** | ||
700 | * @brief Publishes the record defined by the section section | ||
701 | * | ||
702 | * @param cls closure | ||
703 | * @param section the current section | ||
704 | */ | ||
705 | void | ||
706 | publish_iterate (void *cls, const char *section) | ||
707 | { | ||
708 | char *udp_redirects, *tcp_redirects, *alternative_names, *alternative_name, | ||
709 | *keyfile; | ||
710 | |||
711 | GNUNET_CONFIGURATION_get_value_string (servicecfg, section, | ||
712 | "UDP_REDIRECTS", &udp_redirects); | ||
713 | GNUNET_CONFIGURATION_get_value_string (servicecfg, section, "TCP_REDIRECTS", | ||
714 | &tcp_redirects); | ||
715 | |||
716 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "GNUNETD", | ||
717 | "HOSTKEY", | ||
718 | &keyfile)) | ||
719 | { | ||
720 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "could not read keyfile-value\n"); | ||
721 | if (keyfile != NULL) | ||
722 | GNUNET_free (keyfile); | ||
723 | return; | ||
724 | } | ||
725 | |||
726 | struct GNUNET_CRYPTO_RsaPrivateKey *my_private_key = | ||
727 | GNUNET_CRYPTO_rsa_key_create_from_file (keyfile); | ||
728 | GNUNET_free (keyfile); | ||
729 | GNUNET_assert (my_private_key != NULL); | ||
730 | |||
731 | uint64_t ports = get_port_from_redirects (udp_redirects, tcp_redirects); | ||
732 | uint32_t service_type = 0; | ||
733 | |||
734 | if (NULL != udp_redirects) | ||
735 | service_type = GNUNET_DNS_SERVICE_TYPE_UDP; | ||
736 | |||
737 | if (NULL != tcp_redirects) | ||
738 | service_type = GNUNET_DNS_SERVICE_TYPE_TCP; | ||
739 | |||
740 | service_type = htonl (service_type); | ||
741 | |||
742 | |||
743 | publish_name (section, ports, service_type, my_private_key); | ||
744 | |||
745 | GNUNET_CONFIGURATION_get_value_string (servicecfg, section, | ||
746 | "ALTERNATIVE_NAMES", | ||
747 | &alternative_names); | ||
748 | for (alternative_name = strtok (alternative_names, " "); | ||
749 | alternative_name != NULL; alternative_name = strtok (NULL, " ")) | ||
750 | { | ||
751 | char *altname = | ||
752 | alloca (strlen (alternative_name) + strlen (section) + 1 + 1); | ||
753 | strcpy (altname, alternative_name); | ||
754 | strcpy (altname + strlen (alternative_name) + 1, section); | ||
755 | altname[strlen (alternative_name)] = '.'; | ||
756 | |||
757 | publish_name (altname, ports, service_type, my_private_key); | ||
758 | } | ||
759 | |||
760 | GNUNET_free_non_null(alternative_names); | ||
761 | GNUNET_CRYPTO_rsa_key_free (my_private_key); | ||
762 | GNUNET_free_non_null (udp_redirects); | ||
763 | GNUNET_free_non_null (tcp_redirects); | ||
764 | } | ||
765 | |||
766 | /** | ||
767 | * Publish a DNS-record in the DHT. This is up to now just for testing. | ||
768 | */ | ||
769 | static void | ||
770 | publish_names (void *cls, | ||
771 | const struct GNUNET_SCHEDULER_TaskContext *tc) { | ||
772 | char *services; | ||
773 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | ||
774 | return; | ||
775 | |||
776 | if (NULL != servicecfg) | ||
777 | GNUNET_CONFIGURATION_destroy(servicecfg); | ||
778 | |||
779 | GNUNET_CONFIGURATION_get_value_filename(cfg, "dns", "SERVICES", &services); | ||
780 | |||
781 | servicecfg = GNUNET_CONFIGURATION_create(); | ||
782 | if (GNUNET_OK == GNUNET_CONFIGURATION_parse(servicecfg, services)) | ||
614 | { | 783 | { |
615 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "could not sign DNS_Record\n"); | 784 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Parsing services %s\n", services); |
616 | return; | 785 | GNUNET_CONFIGURATION_iterate_sections(servicecfg, publish_iterate, NULL); |
617 | } | 786 | } |
618 | GNUNET_CRYPTO_rsa_key_free(my_private_key); | 787 | if (NULL != services) |
619 | 788 | GNUNET_free(services); | |
620 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
621 | "Putting with key %08x, size = %d\n", | ||
622 | *((unsigned int*)&data.service_descriptor), | ||
623 | size); | ||
624 | |||
625 | GNUNET_DHT_put(dht, | ||
626 | &data.service_descriptor, | ||
627 | DEFAULT_PUT_REPLICATION, | ||
628 | GNUNET_DHT_RO_NONE, | ||
629 | GNUNET_BLOCK_TYPE_DNS, | ||
630 | size, | ||
631 | (char*)&data, | ||
632 | GNUNET_TIME_relative_to_absolute(GNUNET_TIME_UNIT_HOURS), | ||
633 | GNUNET_TIME_UNIT_MINUTES, | ||
634 | NULL, | ||
635 | NULL); | ||
636 | 789 | ||
637 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_HOURS, | 790 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_HOURS, |
638 | publish_name, | 791 | publish_names, |
639 | NULL); | 792 | NULL); |
640 | } | 793 | } |
641 | 794 | ||
@@ -689,7 +842,7 @@ run (void *cls, | |||
689 | 842 | ||
690 | dnsoutport = htons(addr.sin_port); | 843 | dnsoutport = htons(addr.sin_port); |
691 | 844 | ||
692 | GNUNET_SCHEDULER_add_now (publish_name, NULL); | 845 | GNUNET_SCHEDULER_add_now (publish_names, NULL); |
693 | 846 | ||
694 | GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, dnsout, &read_response, NULL); | 847 | GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, dnsout, &read_response, NULL); |
695 | 848 | ||