2 This file is part of GNUnet.
3 Copyright (C) 2009-2013, 2016, 2018 GNUnet e.V.
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
21 * @file gns/gns_tld_api.c
22 * @brief library to access the GNS service, including TLD lookup
23 * @author Martin Schanzenbach
24 * @author Christian Grothoff
27 #include "gnunet_util_lib.h"
28 #include "gnunet_constants.h"
29 #include "gnunet_arm_service.h"
30 #include "gnunet_identity_service.h"
31 #include "gnunet_hello_lib.h"
32 #include "gnunet_protocols.h"
33 #include "gnunet_dht_service.h"
38 #define LOG(kind,...) GNUNET_log_from (kind, "gns-tld-api",__VA_ARGS__)
43 * Handle to a lookup request
45 struct GNUNET_GNS_LookupWithTldRequest
51 struct GNUNET_GNS_Handle *gns_handle;
54 * processor to call on lookup result
56 GNUNET_GNS_LookupResultProcessor2 lookup_proc;
59 * Domain name we are resolving.
64 * @e lookup_proc closure
66 void *lookup_proc_cls;
69 * Underlying GNS lookup.
71 struct GNUNET_GNS_LookupRequest *lr;
74 * Lookup an ego with the identity service.
76 struct GNUNET_IDENTITY_EgoLookup *id_op;
79 * Desired result record type.
86 enum GNUNET_GNS_LocalOptions options;
91 * Obtain the TLD of the given @a name.
94 * @return the part of @a name after the last ".",
95 * or @a name if @a name does not contain a "."
98 get_tld (const char *name)
103 (unsigned char) '.');
107 tld++; /* skip the '.' */
108 return GNUNET_strdup (tld);
113 * Eat the TLD of the given @a name.
115 * @param[in,out] name a name
122 GNUNET_assert (0 < strlen (name));
124 (unsigned char) '.');
127 GNUNET_GNS_EMPTY_LABEL_AT);
134 * Function called with the result of a GNS lookup.
136 * @param cls a `struct GNUNET_GNS_LookupWithTldRequest *`
137 * @param rd_count number of records returned
138 * @param rd array of @a rd_count records with the results
141 process_lookup_result (void *cls,
143 const struct GNUNET_GNSRECORD_Data *rd)
145 struct GNUNET_GNS_LookupWithTldRequest *ltr = cls;
148 ltr->lookup_proc (ltr->lookup_proc_cls,
152 GNUNET_GNS_lookup_with_tld_cancel (ltr);
157 * Perform the actual resolution, starting with the zone
158 * identified by the given public key.
160 * @param pkey public key to use for the zone, can be NULL
163 lookup_with_public_key (struct GNUNET_GNS_LookupWithTldRequest *ltr,
164 const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey)
166 ltr->lr = GNUNET_GNS_lookup (ltr->gns_handle,
171 &process_lookup_result,
177 * Method called to with the ego we are to use for the lookup,
178 * when the ego is determined by a name.
180 * @param cls a `struct GNUNET_GNS_LookupWithTldRequest *`
181 * @param ego ego handle, NULL if not found
184 identity_zone_cb (void *cls,
185 const struct GNUNET_IDENTITY_Ego *ego)
187 struct GNUNET_GNS_LookupWithTldRequest *ltr = cls;
188 struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
193 ltr->lookup_proc (ltr->lookup_proc_cls,
197 GNUNET_GNS_lookup_with_tld_cancel (ltr);
202 GNUNET_IDENTITY_ego_get_public_key (ego,
204 lookup_with_public_key (ltr,
211 * Perform an asynchronous lookup operation on the GNS,
212 * determining the zone using the TLD of the given name
213 * and the current configuration to resolve TLDs to zones.
215 * @param handle handle to the GNS service
216 * @param name the name to look up, including TLD
217 * @param type the record type to look up
218 * @param options local options for the lookup
219 * @param proc processor to call on result
220 * @param proc_cls closure for @a proc
221 * @return handle to the get request, NULL on error (i.e. bad configuration)
223 struct GNUNET_GNS_LookupWithTldRequest *
224 GNUNET_GNS_lookup_with_tld (struct GNUNET_GNS_Handle *handle,
227 enum GNUNET_GNS_LocalOptions options,
228 GNUNET_GNS_LookupResultProcessor2 proc,
231 struct GNUNET_GNS_LookupWithTldRequest *ltr;
235 struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
237 ltr = GNUNET_new (struct GNUNET_GNS_LookupWithTldRequest);
238 ltr->gns_handle = handle;
239 ltr->name = GNUNET_strdup (name);
241 ltr->options = options;
242 ltr->lookup_proc = proc;
243 ltr->lookup_proc_cls = proc_cls;
244 /* start with trivial case: TLD is zkey */
245 tld = get_tld (ltr->name);
247 GNUNET_CRYPTO_ecdsa_public_key_from_string (tld,
252 lookup_with_public_key (ltr,
258 /* second case: TLD is mapped in our configuration file */
259 GNUNET_asprintf (&dot_tld,
263 GNUNET_CONFIGURATION_get_value_string (handle->cfg,
269 GNUNET_CRYPTO_ecdsa_public_key_from_string (zonestr,
273 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
276 _("Expected a base32-encoded public zone key\n"));
277 GNUNET_free (zonestr);
278 GNUNET_free (dot_tld);
279 GNUNET_free (ltr->name);
284 GNUNET_free (dot_tld);
285 GNUNET_free (zonestr);
287 lookup_with_public_key (ltr,
292 GNUNET_free (dot_tld);
294 /* Final case: TLD matches one of our egos */
297 /* if the name is of the form 'label' (and not 'label.SUBDOMAIN'), never go to the DHT */
298 if (NULL == strchr (ltr->name,
299 (unsigned char) '.'))
300 ltr->options = GNUNET_GNS_LO_NO_DHT;
302 ltr->options = GNUNET_GNS_LO_LOCAL_MASTER;
303 ltr->id_op = GNUNET_IDENTITY_ego_lookup (ltr->gns_handle->cfg,
308 if (NULL == ltr->id_op)
310 GNUNET_free (ltr->name);
319 * Cancel pending lookup request
321 * @param ltr the lookup request to cancel
324 GNUNET_GNS_lookup_with_tld_cancel (struct GNUNET_GNS_LookupWithTldRequest *ltr)
326 if (NULL != ltr->id_op)
328 GNUNET_IDENTITY_ego_lookup_cancel (ltr->id_op);
333 GNUNET_GNS_lookup_cancel (ltr->lr);
336 GNUNET_free (ltr->name);
340 /* end of gns_tld_api.c */