From 8bd2218151fa06cd6209a575e3000b74616c4f02 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Mon, 5 Mar 2018 23:10:22 +0100 Subject: adding missing/forgotten files --- src/gns/gns_tld_api.c | 334 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 334 insertions(+) create mode 100644 src/gns/gns_tld_api.c (limited to 'src/gns/gns_tld_api.c') diff --git a/src/gns/gns_tld_api.c b/src/gns/gns_tld_api.c new file mode 100644 index 000000000..c78afa572 --- /dev/null +++ b/src/gns/gns_tld_api.c @@ -0,0 +1,334 @@ +/* + This file is part of GNUnet. + Copyright (C) 2009-2013, 2016, 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 + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +/** + * @file gns/gns_tld_api.c + * @brief library to access the GNS service, including TLD lookup + * @author Martin Schanzenbach + * @author Christian Grothoff + */ +#include "platform.h" +#include "gnunet_util_lib.h" +#include "gnunet_constants.h" +#include "gnunet_arm_service.h" +#include "gnunet_identity_service.h" +#include "gnunet_hello_lib.h" +#include "gnunet_protocols.h" +#include "gnunet_dht_service.h" +#include "gns.h" +#include "gns_api.h" + + +#define LOG(kind,...) GNUNET_log_from (kind, "gns-tld-api",__VA_ARGS__) + + + +/** + * Handle to a lookup request + */ +struct GNUNET_GNS_LookupWithTldRequest +{ + + /** + * handle to gns + */ + struct GNUNET_GNS_Handle *gns_handle; + + /** + * processor to call on lookup result + */ + GNUNET_GNS_LookupResultProcessor2 lookup_proc; + + /** + * Domain name we are resolving. + */ + char *name; + + /** + * @e lookup_proc closure + */ + void *lookup_proc_cls; + + /** + * Underlying GNS lookup. + */ + struct GNUNET_GNS_LookupRequest *lr; + + /** + * Lookup an ego with the identity service. + */ + struct GNUNET_IDENTITY_EgoLookup *id_op; + + /** + * Desired result record type. + */ + uint32_t type; + + /** + * Lookup options. + */ + enum GNUNET_GNS_LocalOptions options; +}; + + +/** + * 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 const char * +get_tld (const char *name) +{ + const char *tld; + + tld = strrchr (name, + (unsigned char) '.'); + if (NULL == tld) + tld = name; + else + tld++; /* skip the '.' */ + return tld; +} + + +/** + * Eat the TLD of the given @a name. + * + * @param name a name + */ +static void +eat_tld (char *name) +{ + char *tld; + + GNUNET_assert (0 < strlen (name)); + tld = strrchr (name, + (unsigned char) '.'); + if (NULL == tld) + strcpy (name, + GNUNET_GNS_MASTERZONE_STR); + else + *tld = '\0'; +} + + +/** + * Function called with the result of a GNS lookup. + * + * @param cls a `struct GNUNET_GNS_LookupWithTldRequest *` + * @param rd_count number of records returned + * @param rd array of @a rd_count records with the results + */ +static void +process_lookup_result (void *cls, + uint32_t rd_count, + const struct GNUNET_GNSRECORD_Data *rd) +{ + struct GNUNET_GNS_LookupWithTldRequest *ltr = cls; + + ltr->lr = NULL; + ltr->lookup_proc (ltr->lookup_proc_cls, + GNUNET_YES, + rd_count, + rd); + GNUNET_GNS_lookup_with_tld_cancel (ltr); +} + + +/** + * Perform the actual resolution, starting with the zone + * identified by the given public key. + * + * @param pkey public key to use for the zone, can be NULL + */ +static void +lookup_with_public_key (struct GNUNET_GNS_LookupWithTldRequest *ltr, + const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey) +{ + ltr->lr = GNUNET_GNS_lookup (ltr->gns_handle, + ltr->name, + pkey, + ltr->type, + ltr->options, + &process_lookup_result, + ltr); +} + + +/** + * Method called to with the ego we are to use for the lookup, + * when the ego is determined by a name. + * + * @param cls a `struct GNUNET_GNS_LookupWithTldRequest *` + * @param ego ego handle, NULL if not found + */ +static void +identity_zone_cb (void *cls, + const struct GNUNET_IDENTITY_Ego *ego) +{ + struct GNUNET_GNS_LookupWithTldRequest *ltr = cls; + struct GNUNET_CRYPTO_EcdsaPublicKey pkey; + + ltr->id_op = NULL; + if (NULL == ego) + { + ltr->lookup_proc (ltr->lookup_proc_cls, + GNUNET_NO, + 0, + NULL); + GNUNET_GNS_lookup_with_tld_cancel (ltr); + return; + } + else + { + GNUNET_IDENTITY_ego_get_public_key (ego, + &pkey); + lookup_with_public_key (ltr, + &pkey); + } +} + + +/** + * Perform an asynchronous lookup operation on the GNS, + * determining the zone using the TLD of the given name + * and the current configuration to resolve TLDs to zones. + * + * @param handle handle to the GNS service + * @param name the name to look up, including TLD + * @param type the record type to look up + * @param options local options for the lookup + * @param proc processor to call on result + * @param proc_cls closure for @a proc + * @return handle to the get request, NULL on error (i.e. bad configuration) + */ +struct GNUNET_GNS_LookupWithTldRequest * +GNUNET_GNS_lookup_with_tld (struct GNUNET_GNS_Handle *handle, + const char *name, + uint32_t type, + enum GNUNET_GNS_LocalOptions options, + GNUNET_GNS_LookupResultProcessor2 proc, + void *proc_cls) +{ + struct GNUNET_GNS_LookupWithTldRequest *ltr; + const char *tld; + char *dot_tld; + char *zonestr; + struct GNUNET_CRYPTO_EcdsaPublicKey pkey; + + ltr = GNUNET_new (struct GNUNET_GNS_LookupWithTldRequest); + ltr->gns_handle = handle; + ltr->name = GNUNET_strdup (name); + ltr->type = type; + ltr->options = options; + ltr->lookup_proc = proc; + ltr->lookup_proc_cls = proc_cls; + /* start with trivial case: TLD is zkey */ + tld = get_tld (ltr->name); + if (GNUNET_OK == + GNUNET_CRYPTO_ecdsa_public_key_from_string (tld, + strlen (tld), + &pkey)) + { + eat_tld (ltr->name); + lookup_with_public_key (ltr, + &pkey); + return ltr; + } + + /* second case: TLD is mapped in our configuration file */ + GNUNET_asprintf (&dot_tld, + ".%s", + tld); + if (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_string (handle->cfg, + "gns", + dot_tld, + &zonestr)) + { + if (GNUNET_OK != + GNUNET_CRYPTO_ecdsa_public_key_from_string (zonestr, + strlen (zonestr), + &pkey)) + { + GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, + "gns", + dot_tld, + _("Expected a base32-encoded public zone key\n")); + GNUNET_free (zonestr); + GNUNET_free (dot_tld); + GNUNET_free (ltr->name); + GNUNET_free (ltr); + return NULL; + } + GNUNET_free (dot_tld); + GNUNET_free (zonestr); + eat_tld (ltr->name); + lookup_with_public_key (ltr, + &pkey); + return ltr; + } + GNUNET_free (dot_tld); + + /* Final case: TLD matches one of our egos */ + eat_tld (ltr->name); + + /* if the name is of the form 'label.gnu', never go to the DHT */ + if (NULL == strchr (ltr->name, + (unsigned char) '.')) + ltr->options = GNUNET_GNS_LO_NO_DHT; + ltr->id_op = GNUNET_IDENTITY_ego_lookup (ltr->gns_handle->cfg, + tld, + &identity_zone_cb, + ltr); + if (NULL == ltr->id_op) + { + GNUNET_free (ltr->name); + GNUNET_free (ltr); + return NULL; + } + return ltr; +} + + +/** + * Cancel pending lookup request + * + * @param ltr the lookup request to cancel + */ +void +GNUNET_GNS_lookup_with_tld_cancel (struct GNUNET_GNS_LookupWithTldRequest *ltr) +{ + if (NULL != ltr->id_op) + { + GNUNET_IDENTITY_ego_lookup_cancel (ltr->id_op); + ltr->id_op = NULL; + } + if (NULL != ltr->lr) + { + GNUNET_GNS_lookup_cancel (ltr->lr); + ltr->lr = NULL; + } + GNUNET_free (ltr->name); + GNUNET_free (ltr); +} + +/* end of gns_tld_api.c */ -- cgit v1.2.3