diff options
Diffstat (limited to 'src/gns/gnunet-gns.c')
-rw-r--r-- | src/gns/gnunet-gns.c | 386 |
1 files changed, 0 insertions, 386 deletions
diff --git a/src/gns/gnunet-gns.c b/src/gns/gnunet-gns.c deleted file mode 100644 index 5cf496808..000000000 --- a/src/gns/gnunet-gns.c +++ /dev/null | |||
@@ -1,386 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2012-2013, 2017-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 gnunet-gns.c | ||
22 | * @brief command line tool to access distributed GNS | ||
23 | * @author Christian Grothoff | ||
24 | */ | ||
25 | #include "platform.h" | ||
26 | #if HAVE_LIBIDN2 | ||
27 | #if HAVE_IDN2_H | ||
28 | #include <idn2.h> | ||
29 | #elif HAVE_IDN2_IDN2_H | ||
30 | #include <idn2/idn2.h> | ||
31 | #endif | ||
32 | #elif HAVE_LIBIDN | ||
33 | #if HAVE_IDNA_H | ||
34 | #include <idna.h> | ||
35 | #elif HAVE_IDN_IDNA_H | ||
36 | #include <idn/idna.h> | ||
37 | #endif | ||
38 | #endif | ||
39 | #include <gnunet_util_lib.h> | ||
40 | #include <gnunet_dnsparser_lib.h> | ||
41 | #include <gnunet_gnsrecord_lib.h> | ||
42 | #include <gnunet_namestore_service.h> | ||
43 | #include <gnunet_gns_service.h> | ||
44 | |||
45 | |||
46 | /** | ||
47 | * Configuration we are using. | ||
48 | */ | ||
49 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
50 | |||
51 | /** | ||
52 | * Handle to GNS service. | ||
53 | */ | ||
54 | static struct GNUNET_GNS_Handle *gns; | ||
55 | |||
56 | /** | ||
57 | * GNS name to lookup. (-u option) | ||
58 | */ | ||
59 | static char *lookup_name; | ||
60 | |||
61 | /** | ||
62 | * DNS IDNA name to lookup. (set if -d option is set) | ||
63 | */ | ||
64 | char *idna_name; | ||
65 | |||
66 | /** | ||
67 | * DNS compatibility (name is given as DNS name, possible IDNA). | ||
68 | */ | ||
69 | static int dns_compat; | ||
70 | |||
71 | /** | ||
72 | * record type to look up (-t option) | ||
73 | */ | ||
74 | static char *lookup_type; | ||
75 | |||
76 | /** | ||
77 | * raw output | ||
78 | */ | ||
79 | static int raw; | ||
80 | |||
81 | /** | ||
82 | * Desired record type. | ||
83 | */ | ||
84 | static uint32_t rtype; | ||
85 | |||
86 | /** | ||
87 | * Timeout for lookup | ||
88 | */ | ||
89 | static struct GNUNET_TIME_Relative timeout; | ||
90 | |||
91 | /** | ||
92 | * Timeout task | ||
93 | */ | ||
94 | static struct GNUNET_SCHEDULER_Task *to_task; | ||
95 | |||
96 | /** | ||
97 | * Handle to lookup request | ||
98 | */ | ||
99 | static struct GNUNET_GNS_LookupWithTldRequest *lr; | ||
100 | |||
101 | /** | ||
102 | * Global return value. | ||
103 | * 0 on success (default), | ||
104 | * 1 on internal failures | ||
105 | * 2 on launch failure, | ||
106 | * 4 if the name is not a GNS-supported TLD, | ||
107 | */ | ||
108 | static int global_ret; | ||
109 | |||
110 | |||
111 | /** | ||
112 | * Task run on shutdown. Cleans up everything. | ||
113 | * | ||
114 | * @param cls unused | ||
115 | */ | ||
116 | static void | ||
117 | do_shutdown (void *cls) | ||
118 | { | ||
119 | (void) cls; | ||
120 | if (NULL != to_task) | ||
121 | { | ||
122 | GNUNET_SCHEDULER_cancel (to_task); | ||
123 | to_task = NULL; | ||
124 | } | ||
125 | if (NULL != lr) | ||
126 | { | ||
127 | GNUNET_GNS_lookup_with_tld_cancel (lr); | ||
128 | lr = NULL; | ||
129 | } | ||
130 | if (NULL != gns) | ||
131 | { | ||
132 | GNUNET_GNS_disconnect (gns); | ||
133 | gns = NULL; | ||
134 | } | ||
135 | if (NULL != idna_name) | ||
136 | { | ||
137 | GNUNET_free (idna_name); | ||
138 | idna_name = NULL; | ||
139 | } | ||
140 | } | ||
141 | |||
142 | |||
143 | /** | ||
144 | * Task to run on timeout | ||
145 | * | ||
146 | * @param cls unused | ||
147 | */ | ||
148 | static void | ||
149 | do_timeout (void*cls) | ||
150 | { | ||
151 | to_task = NULL; | ||
152 | global_ret = 3; // Timeout | ||
153 | GNUNET_SCHEDULER_shutdown (); | ||
154 | } | ||
155 | |||
156 | |||
157 | /** | ||
158 | * Function called with the result of a GNS lookup. | ||
159 | * | ||
160 | * @param cls the 'const char *' name that was resolved | ||
161 | * @param was_gns #GNUNET_NO if TLD did not indicate use of GNS | ||
162 | * @param rd_count number of records returned | ||
163 | * @param rd array of @a rd_count records with the results | ||
164 | */ | ||
165 | static void | ||
166 | process_lookup_result (void *cls, | ||
167 | int was_gns, | ||
168 | uint32_t rd_count, | ||
169 | const struct GNUNET_GNSRECORD_Data *rd) | ||
170 | { | ||
171 | const char *name = cls; | ||
172 | const char *typename; | ||
173 | char *string_val; | ||
174 | |||
175 | lr = NULL; | ||
176 | if (GNUNET_NO == was_gns) | ||
177 | { | ||
178 | global_ret = 4; /* not for GNS */ | ||
179 | GNUNET_SCHEDULER_shutdown (); | ||
180 | return; | ||
181 | } | ||
182 | if (! raw) | ||
183 | { | ||
184 | if (0 == rd_count) | ||
185 | printf ("No results.\n"); | ||
186 | else | ||
187 | printf ("%s:\n", name); | ||
188 | } | ||
189 | for (uint32_t i = 0; i < rd_count; i++) | ||
190 | { | ||
191 | if ((rd[i].record_type != rtype) && (GNUNET_GNSRECORD_TYPE_ANY != rtype)) | ||
192 | continue; | ||
193 | typename = GNUNET_GNSRECORD_number_to_typename (rd[i].record_type); | ||
194 | string_val = GNUNET_GNSRECORD_value_to_string (rd[i].record_type, | ||
195 | rd[i].data, | ||
196 | rd[i].data_size); | ||
197 | if (NULL == string_val) | ||
198 | { | ||
199 | fprintf (stderr, | ||
200 | "Record %u of type %d malformed, skipping\n", | ||
201 | (unsigned int) i, | ||
202 | (int) rd[i].record_type); | ||
203 | continue; | ||
204 | } | ||
205 | if (raw) | ||
206 | printf ("%s\n", string_val); | ||
207 | else | ||
208 | printf ("Got `%s' record: %s%s\n", | ||
209 | typename, | ||
210 | string_val, | ||
211 | (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_SUPPLEMENTAL)) ? | ||
212 | " (supplemental)" : ""); | ||
213 | GNUNET_free (string_val); | ||
214 | } | ||
215 | GNUNET_SCHEDULER_shutdown (); | ||
216 | } | ||
217 | |||
218 | |||
219 | /** | ||
220 | * Main function that will be run. | ||
221 | * | ||
222 | * @param cls closure | ||
223 | * @param args remaining command-line arguments | ||
224 | * @param cfgfile name of the configuration file used (for saving, can be NULL!) | ||
225 | * @param c configuration | ||
226 | */ | ||
227 | static void | ||
228 | run (void *cls, | ||
229 | char *const *args, | ||
230 | const char *cfgfile, | ||
231 | const struct GNUNET_CONFIGURATION_Handle *c) | ||
232 | { | ||
233 | (void) cls; | ||
234 | (void) args; | ||
235 | (void) cfgfile; | ||
236 | |||
237 | cfg = c; | ||
238 | to_task = NULL; | ||
239 | { | ||
240 | char *colon; | ||
241 | |||
242 | if (NULL != (colon = strchr (lookup_name, ':'))) | ||
243 | *colon = '\0'; | ||
244 | } | ||
245 | |||
246 | /** | ||
247 | * If DNS compatibility is requested, we first verify that the | ||
248 | * lookup_name is in a DNS format. If yes, we convert it to UTF-8. | ||
249 | */ | ||
250 | if (GNUNET_YES == dns_compat) | ||
251 | { | ||
252 | Idna_rc rc; | ||
253 | |||
254 | if (GNUNET_OK != GNUNET_DNSPARSER_check_name (lookup_name)) | ||
255 | { | ||
256 | fprintf (stderr, | ||
257 | _ ("`%s' is not a valid DNS domain name\n"), | ||
258 | lookup_name); | ||
259 | global_ret = 3; | ||
260 | return; | ||
261 | } | ||
262 | if (IDNA_SUCCESS != | ||
263 | (rc = idna_to_unicode_8z8z (lookup_name, &idna_name, | ||
264 | IDNA_ALLOW_UNASSIGNED))) | ||
265 | { | ||
266 | fprintf (stderr, | ||
267 | _ ("Failed to convert DNS IDNA name `%s' to UTF-8: %s\n"), | ||
268 | lookup_name, | ||
269 | idna_strerror (rc)); | ||
270 | global_ret = 4; | ||
271 | return; | ||
272 | } | ||
273 | lookup_name = idna_name; | ||
274 | } | ||
275 | |||
276 | if (GNUNET_YES != | ||
277 | GNUNET_CLIENT_test (cfg, | ||
278 | "arm")) | ||
279 | { | ||
280 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
281 | _ ("Cannot resolve using GNS: GNUnet peer not running\n")); | ||
282 | global_ret = 5; | ||
283 | return; | ||
284 | } | ||
285 | to_task = GNUNET_SCHEDULER_add_delayed (timeout, | ||
286 | &do_timeout, | ||
287 | NULL); | ||
288 | gns = GNUNET_GNS_connect (cfg); | ||
289 | if (NULL == gns) | ||
290 | { | ||
291 | fprintf (stderr, | ||
292 | _ ("Failed to connect to GNS\n")); | ||
293 | global_ret = 2; | ||
294 | return; | ||
295 | } | ||
296 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, | ||
297 | NULL); | ||
298 | if (NULL != lookup_type) | ||
299 | rtype = GNUNET_GNSRECORD_typename_to_number (lookup_type); | ||
300 | else | ||
301 | rtype = GNUNET_DNSPARSER_TYPE_A; | ||
302 | if (UINT32_MAX == rtype) | ||
303 | { | ||
304 | fprintf (stderr, | ||
305 | _ ("Invalid typename specified, assuming `ANY'\n")); | ||
306 | rtype = GNUNET_GNSRECORD_TYPE_ANY; | ||
307 | } | ||
308 | lr = GNUNET_GNS_lookup_with_tld (gns, | ||
309 | lookup_name, | ||
310 | rtype, | ||
311 | GNUNET_GNS_LO_DEFAULT, | ||
312 | &process_lookup_result, | ||
313 | lookup_name); | ||
314 | if (NULL == lr) | ||
315 | { | ||
316 | global_ret = 2; | ||
317 | GNUNET_SCHEDULER_shutdown (); | ||
318 | return; | ||
319 | } | ||
320 | } | ||
321 | |||
322 | |||
323 | /** | ||
324 | * The main function for gnunet-gns. | ||
325 | * | ||
326 | * @param argc number of arguments from the command line | ||
327 | * @param argv command line arguments | ||
328 | * @return 0 ok, 1 on error | ||
329 | */ | ||
330 | int | ||
331 | main (int argc, char *const *argv) | ||
332 | { | ||
333 | timeout = GNUNET_TIME_UNIT_FOREVER_REL; | ||
334 | struct GNUNET_GETOPT_CommandLineOption options[] = | ||
335 | { GNUNET_GETOPT_option_mandatory ( | ||
336 | GNUNET_GETOPT_option_string ('u', | ||
337 | "lookup", | ||
338 | "NAME", | ||
339 | gettext_noop ( | ||
340 | "Lookup a record for the given name"), | ||
341 | &lookup_name)), | ||
342 | GNUNET_GETOPT_option_string ('t', | ||
343 | "type", | ||
344 | "TYPE", | ||
345 | gettext_noop ( | ||
346 | "Specify the type of the record to lookup"), | ||
347 | &lookup_type), | ||
348 | GNUNET_GETOPT_option_relative_time ('T', | ||
349 | "timeout", | ||
350 | "TIMEOUT", | ||
351 | gettext_noop ( | ||
352 | "Specify a timeout for the lookup"), | ||
353 | &timeout), | ||
354 | GNUNET_GETOPT_option_flag ('r', | ||
355 | "raw", | ||
356 | gettext_noop ("No unneeded output"), | ||
357 | &raw), | ||
358 | GNUNET_GETOPT_option_flag ('d', | ||
359 | "dns", | ||
360 | gettext_noop ( | ||
361 | "DNS Compatibility: Name is passed in IDNA instead of UTF-8"), | ||
362 | &dns_compat), | ||
363 | GNUNET_GETOPT_OPTION_END }; | ||
364 | int ret; | ||
365 | |||
366 | if (GNUNET_OK != | ||
367 | GNUNET_STRINGS_get_utf8_args (argc, argv, | ||
368 | &argc, &argv)) | ||
369 | return 2; | ||
370 | |||
371 | GNUNET_log_setup ("gnunet-gns", "WARNING", NULL); | ||
372 | ret = GNUNET_PROGRAM_run (argc, | ||
373 | argv, | ||
374 | "gnunet-gns", | ||
375 | _ ("GNUnet GNS resolver tool"), | ||
376 | options, | ||
377 | &run, | ||
378 | NULL); | ||
379 | GNUNET_free_nz ((void *) argv); | ||
380 | if (GNUNET_OK != ret) | ||
381 | return 1; | ||
382 | return global_ret; | ||
383 | } | ||
384 | |||
385 | |||
386 | /* end of gnunet-gns.c */ | ||