From: Philipp Tölke Date: Sat, 5 Mar 2011 11:17:09 +0000 (+0000) Subject: read the dns-config from the file X-Git-Tag: initial-import-from-subversion-38251~19023 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=e01209d5d6b3873646727662ab8dfee0189d42a6;p=oweals%2Fgnunet.git read the dns-config from the file --- 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 @@ -141,6 +141,16 @@ typedef void (*GNUNET_CONFIGURATION_Iterator)(void *cls, const char *value); +/** + * Function to iterate over section. + * + * @param cls closure + * @param section name of the section + */ +typedef void (*GNUNET_CONFIGURATION_Section_Iterator)(void *cls, + const char *section); + + /** * Iterate over all options in the configuration. * @@ -153,6 +163,17 @@ void GNUNET_CONFIGURATION_iterate (const struct GNUNET_CONFIGURATION_Handle *cfg void *iter_cls); +/** + * Iterate over all sections in the configuration. + * + * @param cfg configuration to inspect + * @param iter function to call on each section + * @param iter_cls closure for iter + */ +void GNUNET_CONFIGURATION_iterate_sections (const struct GNUNET_CONFIGURATION_Handle *cfg, + GNUNET_CONFIGURATION_Section_Iterator iter, + void *iter_cls); + /** * Get a configuration value that should be a number. * 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 @@ -401,6 +401,25 @@ GNUNET_CONFIGURATION_iterate (const struct GNUNET_CONFIGURATION_Handle *cfg, } +/** + * Iterate over all sections in the configuration. + * + * @param cfg configuration to inspect + * @param iter function to call on each section + * @param iter_cls closure for iter + */ +void +GNUNET_CONFIGURATION_iterate_sections (const struct GNUNET_CONFIGURATION_Handle *cfg, + GNUNET_CONFIGURATION_Section_Iterator iter, + void *iter_cls) +{ + struct ConfigSection *spos; + + for (spos = cfg->sections; spos != NULL; spos = spos->next) + iter (iter_cls, spos->name); +} + + /** * Copy a configuration value to the given target configuration. * Overwrites existing entries. 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 @@ -60,6 +60,11 @@ static struct GNUNET_DHT_Handle *dht; */ static const struct GNUNET_CONFIGURATION_Handle *cfg; +/** + * The handle to the service-configuration + */ +static struct GNUNET_CONFIGURATION_Handle *servicecfg; + /** * A list of DNS-Responses that have to be sent to the requesting client */ @@ -568,74 +573,222 @@ cleanup_task (void *cls, } /** - * Publish a DNS-record in the DHT. This is up to now just for testing. + * @brief Create a port-map from udp and tcp redirects + * + * @param udp_redirects + * @param tcp_redirects + * + * @return */ -static void -publish_name (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) { - if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) - return; +uint64_t +get_port_from_redirects (const char *udp_redirects, const char *tcp_redirects) +{ + uint64_t ret = 0; + char* cpy, *hostname, *redirect; + int local_port, count = 0; - char* name = "philipptoelke.gnunet."; - size_t size = sizeof(struct GNUNET_DNS_Record); - struct GNUNET_DNS_Record data; - memset(&data, 0, size); + if (NULL != udp_redirects) + { + cpy = GNUNET_strdup (udp_redirects); + for (redirect = strtok (cpy, " "); redirect != NULL; redirect = strtok (NULL, " ")) + { + if (NULL == (hostname = strstr (redirect, ":"))) + { + // FIXME: bitch + continue; + } + hostname[0] = '\0'; + local_port = atoi (redirect); + GNUNET_assert ((local_port > 0) && (local_port < 65536)); // FIXME: don't crash!!! + + ret |= (0xFFFF & htons(local_port)); + ret <<= 16; + count ++; + + if(count > 4) + { + ret = 0; + goto out; + } + } + GNUNET_free(cpy); + cpy = NULL; + } - data.purpose.size = htonl(size - sizeof(struct GNUNET_CRYPTO_RsaSignature)); - data.purpose.purpose = GNUNET_SIGNATURE_PURPOSE_DNS_RECORD; + if (NULL != tcp_redirects) + { + cpy = GNUNET_strdup (tcp_redirects); + for (redirect = strtok (cpy, " "); redirect != NULL; redirect = strtok (NULL, " ")) + { + if (NULL == (hostname = strstr (redirect, ":"))) + { + // FIXME: bitch + continue; + } + hostname[0] = '\0'; + local_port = atoi (redirect); + GNUNET_assert ((local_port > 0) && (local_port < 65536)); // FIXME: don't crash!!! + + ret |= (0xFFFF & htons(local_port)); + ret <<= 16; + count ++; + + if(count > 4) + { + ret = 0; + goto out; + } + } + GNUNET_free(cpy); + cpy = NULL; + } - GNUNET_CRYPTO_hash(name, strlen(name)+1, &data.service_descriptor); - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Store with key1 %x\n", *((unsigned long long*)&data.service_descriptor)); +out: + if (NULL != cpy) + GNUNET_free(cpy); + return ret; +} - data.service_type = htonl(GNUNET_DNS_SERVICE_TYPE_UDP); - data.ports = htons(69); +void +publish_name (const char *name, uint64_t ports, uint32_t service_type, + struct GNUNET_CRYPTO_RsaPrivateKey *my_private_key) +{ + size_t size = sizeof (struct GNUNET_DNS_Record); + struct GNUNET_DNS_Record data; + memset (&data, 0, size); - char* keyfile; - if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename(cfg, "GNUNETD", - "HOSTKEY", &keyfile)) - { - GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "could not read keyfile-value\n"); - if (keyfile != NULL) GNUNET_free(keyfile); - return; - } + data.purpose.size = + htonl (size - sizeof (struct GNUNET_CRYPTO_RsaSignature)); + data.purpose.purpose = GNUNET_SIGNATURE_PURPOSE_DNS_RECORD; + + GNUNET_CRYPTO_hash (name, strlen (name) + 1, &data.service_descriptor); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Store with key1 %x\n", + *((unsigned long long *) &data.service_descriptor)); - struct GNUNET_CRYPTO_RsaPrivateKey *my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file(keyfile); - GNUNET_free(keyfile); - GNUNET_assert(my_private_key != NULL); + data.service_type = service_type; + data.ports = ports; - GNUNET_CRYPTO_rsa_key_get_public(my_private_key, &data.peer); + GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &data.peer); - data.expiration_time = GNUNET_TIME_relative_to_absolute(GNUNET_TIME_UNIT_HOURS); + data.expiration_time = + GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_HOURS, 2)); /* Sign the block */ - if (GNUNET_OK != GNUNET_CRYPTO_rsa_sign(my_private_key, - &data.purpose, - &data.signature)) + if (GNUNET_OK != GNUNET_CRYPTO_rsa_sign (my_private_key, + &data.purpose, &data.signature)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "could not sign DNS_Record\n"); + return; + } + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Putting with key %08x, size = %d\n", + *((unsigned int *) &data.service_descriptor), size); + + GNUNET_DHT_put (dht, + &data.service_descriptor, + DEFAULT_PUT_REPLICATION, + GNUNET_DHT_RO_NONE, + GNUNET_BLOCK_TYPE_DNS, + size, + (char *) &data, + GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_HOURS), + GNUNET_TIME_UNIT_MINUTES, NULL, NULL); +} + +/** + * @brief Publishes the record defined by the section section + * + * @param cls closure + * @param section the current section + */ +void +publish_iterate (void *cls, const char *section) +{ + char *udp_redirects, *tcp_redirects, *alternative_names, *alternative_name, + *keyfile; + + GNUNET_CONFIGURATION_get_value_string (servicecfg, section, + "UDP_REDIRECTS", &udp_redirects); + GNUNET_CONFIGURATION_get_value_string (servicecfg, section, "TCP_REDIRECTS", + &tcp_redirects); + + if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "GNUNETD", + "HOSTKEY", + &keyfile)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "could not read keyfile-value\n"); + if (keyfile != NULL) + GNUNET_free (keyfile); + return; + } + + struct GNUNET_CRYPTO_RsaPrivateKey *my_private_key = + GNUNET_CRYPTO_rsa_key_create_from_file (keyfile); + GNUNET_free (keyfile); + GNUNET_assert (my_private_key != NULL); + + uint64_t ports = get_port_from_redirects (udp_redirects, tcp_redirects); + uint32_t service_type = 0; + + if (NULL != udp_redirects) + service_type = GNUNET_DNS_SERVICE_TYPE_UDP; + + if (NULL != tcp_redirects) + service_type = GNUNET_DNS_SERVICE_TYPE_TCP; + + service_type = htonl (service_type); + + + publish_name (section, ports, service_type, my_private_key); + + GNUNET_CONFIGURATION_get_value_string (servicecfg, section, + "ALTERNATIVE_NAMES", + &alternative_names); + for (alternative_name = strtok (alternative_names, " "); + alternative_name != NULL; alternative_name = strtok (NULL, " ")) + { + char *altname = + alloca (strlen (alternative_name) + strlen (section) + 1 + 1); + strcpy (altname, alternative_name); + strcpy (altname + strlen (alternative_name) + 1, section); + altname[strlen (alternative_name)] = '.'; + + publish_name (altname, ports, service_type, my_private_key); + } + + GNUNET_free_non_null(alternative_names); + GNUNET_CRYPTO_rsa_key_free (my_private_key); + GNUNET_free_non_null (udp_redirects); + GNUNET_free_non_null (tcp_redirects); +} + +/** + * Publish a DNS-record in the DHT. This is up to now just for testing. + */ +static void +publish_names (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) { + char *services; + if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) + return; + + if (NULL != servicecfg) + GNUNET_CONFIGURATION_destroy(servicecfg); + + GNUNET_CONFIGURATION_get_value_filename(cfg, "dns", "SERVICES", &services); + + servicecfg = GNUNET_CONFIGURATION_create(); + if (GNUNET_OK == GNUNET_CONFIGURATION_parse(servicecfg, services)) { - GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "could not sign DNS_Record\n"); - return; + GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Parsing services %s\n", services); + GNUNET_CONFIGURATION_iterate_sections(servicecfg, publish_iterate, NULL); } - GNUNET_CRYPTO_rsa_key_free(my_private_key); - - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Putting with key %08x, size = %d\n", - *((unsigned int*)&data.service_descriptor), - size); - - GNUNET_DHT_put(dht, - &data.service_descriptor, - DEFAULT_PUT_REPLICATION, - GNUNET_DHT_RO_NONE, - GNUNET_BLOCK_TYPE_DNS, - size, - (char*)&data, - GNUNET_TIME_relative_to_absolute(GNUNET_TIME_UNIT_HOURS), - GNUNET_TIME_UNIT_MINUTES, - NULL, - NULL); + if (NULL != services) + GNUNET_free(services); GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_HOURS, - publish_name, + publish_names, NULL); } @@ -689,7 +842,7 @@ run (void *cls, dnsoutport = htons(addr.sin_port); - GNUNET_SCHEDULER_add_now (publish_name, NULL); + GNUNET_SCHEDULER_add_now (publish_names, NULL); GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, dnsout, &read_response, NULL);