aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/include/gnunet_configuration_lib.h21
-rw-r--r--src/util/configuration.c19
-rw-r--r--src/vpn/gnunet-service-dns.c261
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 */
150typedef 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 */
173void 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 */
411void
412GNUNET_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;
61static const struct GNUNET_CONFIGURATION_Handle *cfg; 61static const struct GNUNET_CONFIGURATION_Handle *cfg;
62 62
63/** 63/**
64 * The handle to the service-configuration
65 */
66static 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 */
66static struct answer_packet_list *head; 71static 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 */
573static void 583uint64_t
574publish_name (void *cls, 584get_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); 646out:
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); 652void
591 data.ports = htons(69); 653publish_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 */
705void
706publish_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 */
769static void
770publish_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