X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fgns%2Fgnunet-service-gns.c;h=c376ddfcc390478ec44771d7fa67e33c0cca23a0;hb=620bdac536dff4b17317d9d20b8a6840836d6490;hp=1e8d07bc54c7a9534ef285247330127876ca27b1;hpb=cd9531932c72478a3f7c17eb78238daa2302b2ef;p=oweals%2Fgnunet.git diff --git a/src/gns/gnunet-service-gns.c b/src/gns/gnunet-service-gns.c index 1e8d07bc5..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,14 +29,11 @@ #include "gnunet_dnsparser_lib.h" #include "gnunet_dht_service.h" #include "gnunet_namecache_service.h" -#include "gnunet_namestore_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" #include "gnunet-service-gns_resolver.h" -#include "gnunet-service-gns_reverser.h" -#include "gnunet-service-gns_shorten.h" #include "gnunet-service-gns_interceptor.h" #include "gnunet_protocols.h" @@ -47,7 +44,7 @@ struct GnsClient; /** - * Handle to a lookup operation from api + * Handle to a lookup operation from client via API. */ struct ClientLookupHandle { @@ -79,6 +76,10 @@ struct ClientLookupHandle }; + +/** + * Information we track per connected client. + */ struct GnsClient { /** @@ -103,6 +104,38 @@ struct GnsClient }; +/** + * Representation of a TLD, mapping the respective TLD string + * (i.e. ".gnu") to the respective public key of the zone. + */ +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 DHT */ @@ -114,59 +147,99 @@ static struct GNUNET_DHT_Handle *dht_handle; static struct GNUNET_NAMECACHE_Handle *namecache_handle; /** - * Our handle to the namestore service + * #GNUNET_YES if ipv6 is supported + */ +static int v6_enabled; + +/** + * #GNUNET_YES if ipv4 is supported */ -static struct GNUNET_NAMESTORE_Handle *namestore_handle; +static int v4_enabled; /** - * Our handle to the identity service + * Handle to the statistics service */ -static struct GNUNET_IDENTITY_Handle *identity_handle; +static struct GNUNET_STATISTICS_Handle *statistics; /** - * Our handle to the identity operation to find the master zone - * for intercepted queries. + * Head of DLL of TLDs we map to GNS zones. */ -static struct GNUNET_IDENTITY_Operation *identity_op; +static struct GNS_TopLevelDomain *tld_head; /** - * #GNUNET_YES if ipv6 is supported + * Tail of DLL of TLDs we map to GNS zones. */ -static int v6_enabled; +static struct GNS_TopLevelDomain *tld_tail; + /** - * #GNUNET_YES if ipv4 is supported + * 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 */ -static int v4_enabled; +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; +} + /** - * Handle to the statistics service + * 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 "." */ -static struct GNUNET_STATISTICS_Handle *statistics; +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) { @@ -174,11 +247,6 @@ shutdown_task (void *cls) GNUNET_NO); statistics = NULL; } - if (NULL != namestore_handle) - { - GNUNET_NAMESTORE_disconnect (namestore_handle); - namestore_handle = NULL; - } if (NULL != namecache_handle) { GNUNET_NAMECACHE_disconnect (namecache_handle); @@ -189,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); + } } @@ -207,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); @@ -238,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); @@ -307,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)) { @@ -341,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, @@ -358,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)) && @@ -366,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, @@ -381,53 +467,44 @@ handle_lookup (void *cls, /** - * Method called to inform about the ego to be used for the master zone - * for DNS interceptions. - * - * 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. + * Reads the configuration and populates TLDs * - * @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); } @@ -445,17 +522,13 @@ 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); - namestore_handle = GNUNET_NAMESTORE_connect (c); - if (NULL == namestore_handle) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Failed to connect to the namestore!\n")); - GNUNET_SCHEDULER_shutdown (); - return; - } - namecache_handle = GNUNET_NAMECACHE_connect (c); + namecache_handle = GNUNET_NAMECACHE_connect (c); if (NULL == namecache_handle) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -479,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); }