aboutsummaryrefslogtreecommitdiff
path: root/src/gns/gns_tld_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gns/gns_tld_api.c')
-rw-r--r--src/gns/gns_tld_api.c353
1 files changed, 0 insertions, 353 deletions
diff --git a/src/gns/gns_tld_api.c b/src/gns/gns_tld_api.c
deleted file mode 100644
index 1b711cf40..000000000
--- a/src/gns/gns_tld_api.c
+++ /dev/null
@@ -1,353 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009-2013, 2016, 2018 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero 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.
9
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.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20/**
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
25 */
26#include "platform.h"
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"
34#include "gns.h"
35#include "gns_api.h"
36
37
38#define LOG(kind, ...) GNUNET_log_from (kind, "gns-tld-api", __VA_ARGS__)
39
40
41/**
42 * Handle to a lookup request
43 */
44struct GNUNET_GNS_LookupWithTldRequest
45{
46 /**
47 * handle to gns
48 */
49 struct GNUNET_GNS_Handle *gns_handle;
50
51 /**
52 * processor to call on lookup result
53 */
54 GNUNET_GNS_LookupResultProcessor2 lookup_proc;
55
56 /**
57 * Domain name we are resolving.
58 */
59 char *name;
60
61 /**
62 * @e lookup_proc closure
63 */
64 void *lookup_proc_cls;
65
66 /**
67 * Underlying GNS lookup.
68 */
69 struct GNUNET_GNS_LookupRequest *lr;
70
71 /**
72 * Lookup an ego with the identity service.
73 */
74 struct GNUNET_IDENTITY_EgoSuffixLookup *id_co;
75
76 /**
77 * Name of the longest matching ego found so far.
78 * Must be freed on termination.
79 */
80 char *longest_match;
81
82 /**
83 * Ego corresponding to @e longest_match.
84 */
85 struct GNUNET_IDENTITY_Ego *longest_match_ego;
86
87 /**
88 * Desired result record type.
89 */
90 uint32_t type;
91
92 /**
93 * Lookup options.
94 */
95 enum GNUNET_GNS_LocalOptions options;
96};
97
98
99/**
100 * Obtain the TLD of the given @a name.
101 *
102 * @param name a name
103 * @return the part of @a name after the last ".",
104 * or @a name if @a name does not contain a "."
105 */
106static const char *
107get_tld (const char *name)
108{
109 const char *tld;
110
111 tld = strrchr (name, (unsigned char) '.');
112 if (NULL == tld)
113 tld = name;
114 else
115 tld++; /* skip the '.' */
116 return tld;
117}
118
119
120/**
121 * Eat the "TLD" (last bit) of the given @a name.
122 *
123 * @param[in,out] name a name
124 * @param tld what to eat (can be more than just the tld)
125 */
126static void
127eat_tld (char *name, const char *tld)
128{
129 GNUNET_assert (0 < strlen (name));
130 if ((NULL == tld) || (strlen (name) == strlen (tld)))
131 {
132 strcpy (name, GNUNET_GNS_EMPTY_LABEL_AT);
133 }
134 else
135 {
136 GNUNET_assert (strlen (tld) < strlen (name));
137 name[strlen (name) - strlen (tld) - 1] = '\0';
138 }
139}
140
141
142/**
143 * Function called with the result of a GNS lookup.
144 *
145 * @param cls a `struct GNUNET_GNS_LookupWithTldRequest *`
146 * @param rd_count number of records returned
147 * @param rd array of @a rd_count records with the results
148 */
149static void
150process_lookup_result (void *cls,
151 uint32_t rd_count,
152 const struct GNUNET_GNSRECORD_Data *rd)
153{
154 struct GNUNET_GNS_LookupWithTldRequest *ltr = cls;
155
156 ltr->lr = NULL;
157 ltr->lookup_proc (ltr->lookup_proc_cls, GNUNET_YES, rd_count, rd);
158 GNUNET_GNS_lookup_with_tld_cancel (ltr);
159}
160
161
162/**
163 * Perform the actual resolution, starting with the zone
164 * identified by the given public key.
165 *
166 * @param pkey public key to use for the zone, can be NULL
167 */
168static void
169lookup_with_public_key (struct GNUNET_GNS_LookupWithTldRequest *ltr,
170 const struct GNUNET_IDENTITY_PublicKey *pkey)
171{
172 ltr->lr = GNUNET_GNS_lookup (ltr->gns_handle,
173 ltr->name,
174 pkey,
175 ltr->type,
176 ltr->options,
177 &process_lookup_result,
178 ltr);
179}
180
181
182/**
183 * Method called to with the ego we are to use for the lookup,
184 * when the ego is determined by a name.
185 *
186 * @param cls a `struct GNUNET_GNS_LookupWithTldRequest *`
187 * @param ego ego handle, NULL at the end of the iteration
188 * @param ctx context we could store data to associate with @e ego
189 * @param name name of the ego
190 */
191static void
192identity_zone_cb (void *cls,
193 const struct GNUNET_IDENTITY_PrivateKey *priv,
194 const char *ego_name)
195{
196 struct GNUNET_GNS_LookupWithTldRequest *ltr = cls;
197 struct GNUNET_IDENTITY_PublicKey pkey;
198
199 ltr->id_co = NULL;
200 if (NULL == priv)
201 {
202 /* no matching ego found */
203 ltr->lookup_proc (ltr->lookup_proc_cls, GNUNET_NO, 0, NULL);
204 return;
205 }
206 /* Final case: TLD matches one of our egos */
207 if (0 == strcmp (ltr->name, ego_name))
208 {
209 /* name matches ego name perfectly, only "@" remains */
210 strcpy (ltr->name, GNUNET_GNS_EMPTY_LABEL_AT);
211 }
212 else
213 {
214 GNUNET_assert (strlen (ego_name) < strlen (ltr->name));
215 ltr->name[strlen (ltr->name) - strlen (ego_name) - 1] = '\0';
216 }
217 /* if the name is of the form 'label' (and not 'label.SUBDOMAIN'), never go to the DHT */
218 if (NULL == strchr (ltr->name, (unsigned char) '.'))
219 ltr->options = GNUNET_GNS_LO_NO_DHT;
220 else
221 ltr->options = GNUNET_GNS_LO_LOCAL_MASTER;
222 GNUNET_IDENTITY_key_get_public (priv, &pkey);
223 lookup_with_public_key (ltr, &pkey);
224}
225
226
227/**
228 * Perform an asynchronous lookup operation on the GNS,
229 * determining the zone using the TLD of the given name
230 * and the current configuration to resolve TLDs to zones.
231 *
232 * @param handle handle to the GNS service
233 * @param name the name to look up, including TLD (in UTF-8 encoding)
234 * @param type the record type to look up
235 * @param options local options for the lookup
236 * @param proc processor to call on result
237 * @param proc_cls closure for @a proc
238 * @return handle to the get request, NULL on error (e.g. bad configuration)
239 */
240struct GNUNET_GNS_LookupWithTldRequest *
241GNUNET_GNS_lookup_with_tld (struct GNUNET_GNS_Handle *handle,
242 const char *name,
243 uint32_t type,
244 enum GNUNET_GNS_LocalOptions options,
245 GNUNET_GNS_LookupResultProcessor2 proc,
246 void *proc_cls)
247{
248 struct GNUNET_GNS_LookupWithTldRequest *ltr;
249 const char *tld;
250 char *dot_tld;
251 char *zonestr;
252 struct GNUNET_IDENTITY_PublicKey pkey;
253
254 ltr = GNUNET_new (struct GNUNET_GNS_LookupWithTldRequest);
255 ltr->gns_handle = handle;
256 ltr->name = GNUNET_strdup (name);
257 ltr->type = type;
258 ltr->options = options;
259 ltr->lookup_proc = proc;
260 ltr->lookup_proc_cls = proc_cls;
261 /* start with trivial case: TLD is zkey */
262 tld = get_tld (ltr->name);
263 if (GNUNET_OK ==
264 GNUNET_IDENTITY_public_key_from_string (tld, &pkey))
265 {
266 LOG (GNUNET_ERROR_TYPE_DEBUG,
267 "`%s' seems to be a valid zone key\n", tld);
268 eat_tld (ltr->name, tld);
269 lookup_with_public_key (ltr, &pkey);
270 return ltr;
271 }
272
273 /* second case: domain is mapped in our configuration file */
274 for (const char *domain = name; NULL != domain;
275 domain = strchr (domain, (unsigned char) '.'))
276 {
277 if ('.' == domain[0])
278 domain++;
279 GNUNET_asprintf (&dot_tld, ".%s", domain);
280 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (handle->cfg,
281 "gns",
282 dot_tld,
283 &zonestr))
284 {
285 if (GNUNET_OK !=
286 GNUNET_IDENTITY_public_key_from_string (zonestr,
287 &pkey))
288 {
289 GNUNET_log_config_invalid (
290 GNUNET_ERROR_TYPE_ERROR,
291 "gns",
292 dot_tld,
293 _ ("Expected a base32-encoded public zone key\n"));
294 GNUNET_free (zonestr);
295 GNUNET_free (dot_tld);
296 GNUNET_free (ltr->name);
297 GNUNET_free (ltr);
298 return NULL;
299 }
300 eat_tld (ltr->name, &dot_tld[1]);
301 GNUNET_free (zonestr);
302 GNUNET_free (dot_tld);
303 lookup_with_public_key (ltr, &pkey);
304 return ltr;
305 }
306 GNUNET_free (dot_tld);
307 }
308 LOG (GNUNET_ERROR_TYPE_DEBUG,
309 "`%s' should be a valid ego\n", ltr->name);
310 ltr->id_co =
311 GNUNET_IDENTITY_ego_lookup_by_suffix (ltr->gns_handle->cfg,
312 ltr->name,
313 &identity_zone_cb,
314 ltr);
315 if (NULL == ltr->id_co)
316 {
317 GNUNET_free (ltr->name);
318 GNUNET_free (ltr);
319 return NULL;
320 }
321 return ltr;
322}
323
324
325/**
326 * Cancel pending lookup request
327 *
328 * @param ltr the lookup request to cancel
329 * @return closure from the lookup result processor
330 */
331void *
332GNUNET_GNS_lookup_with_tld_cancel (struct GNUNET_GNS_LookupWithTldRequest *ltr)
333{
334 void *ret = ltr->lookup_proc_cls;
335
336 if (NULL != ltr->id_co)
337 {
338 GNUNET_IDENTITY_ego_lookup_by_suffix_cancel (ltr->id_co);
339 ltr->id_co = NULL;
340 }
341 if (NULL != ltr->lr)
342 {
343 GNUNET_GNS_lookup_cancel (ltr->lr);
344 ltr->lr = NULL;
345 }
346 GNUNET_free (ltr->longest_match);
347 GNUNET_free (ltr->name);
348 GNUNET_free (ltr);
349 return ret;
350}
351
352
353/* end of gns_tld_api.c */