X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fgns%2Fgnunet-service-gns.c;h=c376ddfcc390478ec44771d7fa67e33c0cca23a0;hb=620bdac536dff4b17317d9d20b8a6840836d6490;hp=570c07fdfbd3fbd4184b880b6e96e3c022b977c6;hpb=945443b67fe95893ceb711e1bcd7049477f3cba7;p=oweals%2Fgnunet.git diff --git a/src/gns/gnunet-service-gns.c b/src/gns/gnunet-service-gns.c index 570c07fdf..c376ddfcc 100644 --- a/src/gns/gnunet-service-gns.c +++ b/src/gns/gnunet-service-gns.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - Copyright (C) 2011-2013 GNUnet e.V. + Copyright (C) 2011-2018 GNUnet e.V. GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -29,7 +29,7 @@ #include "gnunet_dnsparser_lib.h" #include "gnunet_dht_service.h" #include "gnunet_namecache_service.h" -#include "gnunet_identity_service.h" +#include "gnunet_gnsrecord_lib.h" #include "gnunet_gns_service.h" #include "gnunet_statistics_service.h" #include "gns.h" @@ -44,7 +44,7 @@ struct GnsClient; /** - * Handle to a lookup operation from api + * Handle to a lookup operation from client via API. */ struct ClientLookupHandle { @@ -76,6 +76,10 @@ struct ClientLookupHandle }; + +/** + * Information we track per connected client. + */ struct GnsClient { /** @@ -101,25 +105,46 @@ struct GnsClient /** - * Our handle to the DHT + * Representation of a TLD, mapping the respective TLD string + * (i.e. ".gnu") to the respective public key of the zone. */ -static struct GNUNET_DHT_Handle *dht_handle; +struct GNS_TopLevelDomain +{ + + /** + * Kept in a DLL, as there are unlikely enough of these to + * warrant a hash map. + */ + struct GNS_TopLevelDomain *next; + + /** + * Kept in a DLL, as there are unlikely enough of these to + * warrant a hash map. + */ + struct GNS_TopLevelDomain *prev; + + /** + * Public key associated with the @a tld. + */ + struct GNUNET_CRYPTO_EcdsaPublicKey pkey; + + /** + * Top-level domain as a string, including leading ".". + */ + char *tld; + +}; -/** - * Our handle to the namecache service - */ -static struct GNUNET_NAMECACHE_Handle *namecache_handle; /** - * Our handle to the identity service + * Our handle to the DHT */ -static struct GNUNET_IDENTITY_Handle *identity_handle; +static struct GNUNET_DHT_Handle *dht_handle; /** - * Our handle to the identity operation to find the master zone - * for intercepted queries. + * Our handle to the namecache service */ -static struct GNUNET_IDENTITY_Operation *identity_op; +static struct GNUNET_NAMECACHE_Handle *namecache_handle; /** * #GNUNET_YES if ipv6 is supported @@ -136,29 +161,85 @@ static int v4_enabled; */ static struct GNUNET_STATISTICS_Handle *statistics; +/** + * Head of DLL of TLDs we map to GNS zones. + */ +static struct GNS_TopLevelDomain *tld_head; + +/** + * Tail of DLL of TLDs we map to GNS zones. + */ +static struct GNS_TopLevelDomain *tld_tail; + + +/** + * Find GNS zone belonging to TLD @a tld. + * + * @param tld_str top-level domain to look up + * @param[out] pkey public key to set + * @return #GNUNET_YES if @a tld was found #GNUNET_NO if not + */ +int +GNS_find_tld (const char *tld_str, + struct GNUNET_CRYPTO_EcdsaPublicKey *pkey) +{ + if ('\0' == *tld_str) + return GNUNET_NO; + for (struct GNS_TopLevelDomain *tld = tld_head; + NULL != tld; + tld = tld->next) + { + if (0 == strcasecmp (tld_str, + tld->tld)) + { + *pkey = tld->pkey; + return GNUNET_YES; + } + } + if (GNUNET_OK == + GNUNET_GNSRECORD_zkey_to_pkey (tld_str + 1, + pkey)) + return GNUNET_YES; /* TLD string *was* the public key */ + return GNUNET_NO; +} + + +/** + * Obtain the TLD of the given @a name. + * + * @param name a name + * @return the part of @a name after the last ".", + * or @a name if @a name does not contain a "." + */ +const char * +GNS_get_tld (const char *name) +{ + const char *tld; + + tld = strrchr (name, + (unsigned char) '.'); + if (NULL == tld) + tld = name; + else + tld++; /* skip the '.' */ + return tld; +} + /** * Task run during shutdown. * - * @param cls unused - * @param tc unused + * @param cls unused, NULL */ static void shutdown_task (void *cls) { + struct GNS_TopLevelDomain *tld; + + (void) cls; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down!\n"); GNS_interceptor_done (); - if (NULL != identity_op) - { - GNUNET_IDENTITY_cancel (identity_op); - identity_op = NULL; - } - if (NULL != identity_handle) - { - GNUNET_IDENTITY_disconnect (identity_handle); - identity_handle = NULL; - } GNS_resolver_done (); if (NULL != statistics) { @@ -176,6 +257,14 @@ shutdown_task (void *cls) GNUNET_DHT_disconnect (dht_handle); dht_handle = NULL; } + while (NULL != (tld = tld_head)) + { + GNUNET_CONTAINER_DLL_remove (tld_head, + tld_tail, + tld); + GNUNET_free (tld->tld); + GNUNET_free (tld); + } } @@ -194,6 +283,7 @@ client_disconnect_cb (void *cls, struct ClientLookupHandle *clh; struct GnsClient *gc = app_ctx; + (void) cls; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p disconnected\n", client); @@ -225,6 +315,8 @@ client_connect_cb (void *cls, struct GNUNET_MQ_Handle *mq) { struct GnsClient *gc; + + (void) cls; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p connected\n", client); @@ -294,6 +386,7 @@ check_lookup (void *cls, size_t msg_size; const char* name; + (void) cls; msg_size = ntohs (l_msg->header.size); if (msg_size < sizeof (struct LookupMessage)) { @@ -328,11 +421,13 @@ handle_lookup (void *cls, char *nameptr = name; const char *utf_in; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Received LOOKUP message\n"); GNUNET_SERVICE_client_continue (gc->client); utf_in = (const char *) &sh_msg[1]; - GNUNET_STRINGS_utf8_tolower (utf_in, nameptr); + GNUNET_STRINGS_utf8_tolower (utf_in, + nameptr); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received LOOKUP `%s' message\n", + name); clh = GNUNET_new (struct ClientLookupHandle); GNUNET_CONTAINER_DLL_insert (gc->clh_head, @@ -345,7 +440,9 @@ handle_lookup (void *cls, { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "LOOKUP: Query for A record but AF_INET not supported!"); - send_lookup_response (clh, 0, NULL); + send_lookup_response (clh, + 0, + NULL); return; } if ( (GNUNET_DNSPARSER_TYPE_AAAA == ntohl (sh_msg->type)) && @@ -353,7 +450,9 @@ handle_lookup (void *cls, { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "LOOKUP: Query for AAAA record but AF_INET6 not supported!"); - send_lookup_response (clh, 0, NULL); + send_lookup_response (clh, + 0, + NULL); return; } clh->lookup = GNS_resolver_lookup (&sh_msg->zone, @@ -368,53 +467,44 @@ handle_lookup (void *cls, /** - * Method called to inform about the ego to be used for the master zone - * for DNS interceptions. + * Reads the configuration and populates TLDs * - * This function is only called ONCE, and 'NULL' being passed in - * @a ego does indicate that interception is not configured. - * If @a ego is non-NULL, we should start to intercept DNS queries - * and resolve ".gnu" queries using the given ego as the master zone. - * - * @param cls closure, our `const struct GNUNET_CONFIGURATION_Handle *c` - * @param ego ego handle - * @param ctx context for application to store data for this ego - * (during the lifetime of this process, initially NULL) - * @param name name assigned by the user for this ego, - * NULL if the user just deleted the ego and it - * must thus no longer be used + * @param cls unused + * @param section name of section in config, always "gns" + * @param option name of the option, TLDs start with "." + * @param value value for the option, public key for TLDs */ static void -identity_intercept_cb (void *cls, - struct GNUNET_IDENTITY_Ego *ego, - void **ctx, - const char *name) +read_service_conf (void *cls, + const char *section, + const char *option, + const char *value) { - const struct GNUNET_CONFIGURATION_Handle *cfg = cls; - struct GNUNET_CRYPTO_EcdsaPublicKey dns_root; - - identity_op = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Looking for gns-intercept ego\n"); - if (NULL == ego) - { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - _("No ego configured for `%s`\n"), - "gns-intercept"); + struct GNUNET_CRYPTO_EcdsaPublicKey pk; + struct GNS_TopLevelDomain *tld; + (void) cls; + (void) section; + if (option[0] != '.') return; - } - GNUNET_IDENTITY_ego_get_public_key (ego, - &dns_root); - if (GNUNET_SYSERR == - GNS_interceptor_init (&dns_root, - cfg)) + if (GNUNET_OK != + GNUNET_STRINGS_string_to_data (value, + strlen (value), + &pk, + sizeof (pk))) { - GNUNET_break (0); - GNUNET_SCHEDULER_add_now (&shutdown_task, - NULL); + GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, + section, + option, + _("Properly base32-encoded public key required")); return; } + tld = GNUNET_new (struct GNS_TopLevelDomain); + tld->tld = GNUNET_strdup (&option[1]); + tld->pkey = pk; + GNUNET_CONTAINER_DLL_insert (tld_head, + tld_tail, + tld); } @@ -432,6 +522,10 @@ run (void *cls, { unsigned long long max_parallel_bg_queries = 16; + GNUNET_CONFIGURATION_iterate_section_values (c, + "gns", + &read_service_conf, + NULL); v6_enabled = GNUNET_NETWORK_test_pf (PF_INET6); v4_enabled = GNUNET_NETWORK_test_pf (PF_INET); namecache_handle = GNUNET_NAMECACHE_connect (c); @@ -458,32 +552,28 @@ run (void *cls, { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Could not connect to DHT!\n")); - GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); + GNUNET_SCHEDULER_add_now (&shutdown_task, + NULL); return; } - - identity_handle = GNUNET_IDENTITY_connect (c, - NULL, - NULL); - if (NULL == identity_handle) - { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Could not connect to identity service!\n"); - } - else - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Looking for gns-intercept ego\n"); - identity_op = GNUNET_IDENTITY_get (identity_handle, - "gns-intercept", - &identity_intercept_cb, - (void *) c); - } GNS_resolver_init (namecache_handle, dht_handle, c, max_parallel_bg_queries); - statistics = GNUNET_STATISTICS_create ("gns", c); + if ( (GNUNET_YES == + GNUNET_CONFIGURATION_get_value_yesno (c, + "gns", + "INTERCEPT_DNS")) && + (GNUNET_SYSERR == + GNS_interceptor_init (c)) ) + { + GNUNET_break (0); + GNUNET_SCHEDULER_add_now (&shutdown_task, + NULL); + return; + } + statistics = GNUNET_STATISTICS_create ("gns", + c); GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); }