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 it
6 under the terms of the GNU General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your 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 Affero General Public License for more details.
16 * @file gns/gns_tld_api.c
17 * @brief library to access the GNS service, including TLD lookup
18 * @author Martin Schanzenbach
19 * @author Christian Grothoff
22 #include "gnunet_util_lib.h"
23 #include "gnunet_constants.h"
24 #include "gnunet_arm_service.h"
25 #include "gnunet_identity_service.h"
26 #include "gnunet_hello_lib.h"
27 #include "gnunet_protocols.h"
28 #include "gnunet_dht_service.h"
33 #define LOG(kind,...) GNUNET_log_from (kind, "gns-tld-api",__VA_ARGS__)
38 * Handle to a lookup request
40 struct GNUNET_GNS_LookupWithTldRequest
46 struct GNUNET_GNS_Handle *gns_handle;
49 * processor to call on lookup result
51 GNUNET_GNS_LookupResultProcessor2 lookup_proc;
54 * Domain name we are resolving.
59 * @e lookup_proc closure
61 void *lookup_proc_cls;
64 * Underlying GNS lookup.
66 struct GNUNET_GNS_LookupRequest *lr;
69 * Lookup an ego with the identity service.
71 struct GNUNET_IDENTITY_EgoLookup *id_op;
74 * Desired result record type.
81 enum GNUNET_GNS_LocalOptions options;
86 * Obtain the TLD of the given @a name.
89 * @return the part of @a name after the last ".",
90 * or @a name if @a name does not contain a "."
93 get_tld (const char *name)
102 tld++; /* skip the '.' */
103 return GNUNET_strdup (tld);
108 * Eat the TLD of the given @a name.
110 * @param[in,out] name a name
117 GNUNET_assert (0 < strlen (name));
119 (unsigned char) '.');
122 GNUNET_GNS_EMPTY_LABEL_AT);
129 * Function called with the result of a GNS lookup.
131 * @param cls a `struct GNUNET_GNS_LookupWithTldRequest *`
132 * @param rd_count number of records returned
133 * @param rd array of @a rd_count records with the results
136 process_lookup_result (void *cls,
138 const struct GNUNET_GNSRECORD_Data *rd)
140 struct GNUNET_GNS_LookupWithTldRequest *ltr = cls;
143 ltr->lookup_proc (ltr->lookup_proc_cls,
147 GNUNET_GNS_lookup_with_tld_cancel (ltr);
152 * Perform the actual resolution, starting with the zone
153 * identified by the given public key.
155 * @param pkey public key to use for the zone, can be NULL
158 lookup_with_public_key (struct GNUNET_GNS_LookupWithTldRequest *ltr,
159 const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey)
161 ltr->lr = GNUNET_GNS_lookup (ltr->gns_handle,
166 &process_lookup_result,
172 * Method called to with the ego we are to use for the lookup,
173 * when the ego is determined by a name.
175 * @param cls a `struct GNUNET_GNS_LookupWithTldRequest *`
176 * @param ego ego handle, NULL if not found
179 identity_zone_cb (void *cls,
180 const struct GNUNET_IDENTITY_Ego *ego)
182 struct GNUNET_GNS_LookupWithTldRequest *ltr = cls;
183 struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
188 ltr->lookup_proc (ltr->lookup_proc_cls,
192 GNUNET_GNS_lookup_with_tld_cancel (ltr);
197 GNUNET_IDENTITY_ego_get_public_key (ego,
199 lookup_with_public_key (ltr,
206 * Perform an asynchronous lookup operation on the GNS,
207 * determining the zone using the TLD of the given name
208 * and the current configuration to resolve TLDs to zones.
210 * @param handle handle to the GNS service
211 * @param name the name to look up, including TLD
212 * @param type the record type to look up
213 * @param options local options for the lookup
214 * @param proc processor to call on result
215 * @param proc_cls closure for @a proc
216 * @return handle to the get request, NULL on error (i.e. bad configuration)
218 struct GNUNET_GNS_LookupWithTldRequest *
219 GNUNET_GNS_lookup_with_tld (struct GNUNET_GNS_Handle *handle,
222 enum GNUNET_GNS_LocalOptions options,
223 GNUNET_GNS_LookupResultProcessor2 proc,
226 struct GNUNET_GNS_LookupWithTldRequest *ltr;
230 struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
232 ltr = GNUNET_new (struct GNUNET_GNS_LookupWithTldRequest);
233 ltr->gns_handle = handle;
234 ltr->name = GNUNET_strdup (name);
236 ltr->options = options;
237 ltr->lookup_proc = proc;
238 ltr->lookup_proc_cls = proc_cls;
239 /* start with trivial case: TLD is zkey */
240 tld = get_tld (ltr->name);
242 GNUNET_CRYPTO_ecdsa_public_key_from_string (tld,
247 lookup_with_public_key (ltr,
253 /* second case: TLD is mapped in our configuration file */
254 GNUNET_asprintf (&dot_tld,
258 GNUNET_CONFIGURATION_get_value_string (handle->cfg,
264 GNUNET_CRYPTO_ecdsa_public_key_from_string (zonestr,
268 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
271 _("Expected a base32-encoded public zone key\n"));
272 GNUNET_free (zonestr);
273 GNUNET_free (dot_tld);
274 GNUNET_free (ltr->name);
279 GNUNET_free (dot_tld);
280 GNUNET_free (zonestr);
282 lookup_with_public_key (ltr,
287 GNUNET_free (dot_tld);
289 /* Final case: TLD matches one of our egos */
292 /* if the name is of the form 'label' (and not 'label.SUBDOMAIN'), never go to the DHT */
293 if (NULL == strchr (ltr->name,
294 (unsigned char) '.'))
295 ltr->options = GNUNET_GNS_LO_NO_DHT;
297 ltr->options = GNUNET_GNS_LO_LOCAL_MASTER;
298 ltr->id_op = GNUNET_IDENTITY_ego_lookup (ltr->gns_handle->cfg,
303 if (NULL == ltr->id_op)
305 GNUNET_free (ltr->name);
314 * Cancel pending lookup request
316 * @param ltr the lookup request to cancel
319 GNUNET_GNS_lookup_with_tld_cancel (struct GNUNET_GNS_LookupWithTldRequest *ltr)
321 if (NULL != ltr->id_op)
323 GNUNET_IDENTITY_ego_lookup_cancel (ltr->id_op);
328 GNUNET_GNS_lookup_cancel (ltr->lr);
331 GNUNET_free (ltr->name);
335 /* end of gns_tld_api.c */