From 0f4032609d5372978e0c038ee05f51ce9c131876 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Mon, 5 Mar 2018 20:00:21 +0100 Subject: [PATCH] add convenience API to gnunetgns lib --- doc/man/gnunet-gns.1 | 5 +- po/POTFILES.in | 1 + src/gns/Makefile.am | 5 +- src/gns/gns_api.c | 52 +----- src/gns/gnunet-gns.c | 290 +++++-------------------------- src/include/gnunet_gns_service.h | 54 ++++++ 6 files changed, 106 insertions(+), 301 deletions(-) diff --git a/doc/man/gnunet-gns.1 b/doc/man/gnunet-gns.1 index a6f27479a..4d52cfa97 100644 --- a/doc/man/gnunet-gns.1 +++ b/doc/man/gnunet-gns.1 @@ -32,9 +32,6 @@ Use LOGLEVEL for logging. Valid values are DEBUG, INFO, WARNING and ERROR. Name to lookup. Resolve the specified name using the GNU Name System. .B -.IP "\-T DELAY, \-\-timeout=DELAY" -Set the timeout to DELAY. By default, gnunet\-gns will continue to try to resolve the name until there is a definitive answer or until the user aborts with CTRL\-C. -.B .IP "\-t TYPE, \-\-type=TYPE" Resource Record Type (TYPE) to look for. Supported TYPE's are: A, AAAA, CNAME, NS, PKEY, PSEU, TLSA, SRV, SOA, MX, LEHO, VPN, REV, PTR, TXT @@ -48,7 +45,7 @@ Print GNUnet version number. .SH RETURN VALUE gnunet\-gns will return 0 on success, 1 on internal failures, 2 on launch failures, -3 if the given name is not configured to use GNS, and 4 on timeout. +3 if the given name is not configured to use GNS. .SH BUGS diff --git a/po/POTFILES.in b/po/POTFILES.in index 6ceb95cbd..5804b980c 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -168,6 +168,7 @@ src/fs/gnunet-service-fs_put.c src/fs/gnunet-unindex.c src/fs/plugin_block_fs.c src/gns/gns_api.c +src/gns/gns_tld_api.c src/gns/gnunet-bcd.c src/gns/gnunet-dns2gns.c src/gns/gnunet-gns.c diff --git a/src/gns/Makefile.am b/src/gns/Makefile.am index e89192414..57b096b96 100644 --- a/src/gns/Makefile.am +++ b/src/gns/Makefile.am @@ -111,7 +111,6 @@ gnunet_gns_SOURCES = \ gnunet_gns_LDADD = \ libgnunetgns.la \ $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ - $(top_builddir)/src/identity/libgnunetidentity.la \ $(top_builddir)/src/util/libgnunetutil.la \ $(GN_LIBINTL) @@ -214,9 +213,11 @@ libw32nsp_la_LDFLAGS = \ -no-undefined -static-libgcc libgnunetgns_la_SOURCES = \ - gns_api.c gns.h + gns_api.c gns_api.h \ + gns_tld_api.c gns.h libgnunetgns_la_LIBADD = \ $(top_builddir)/src/util/libgnunetutil.la $(XLIB) \ + $(top_builddir)/src/identity/libgnunetidentity.la \ $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la libgnunetgns_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) diff --git a/src/gns/gns_api.c b/src/gns/gns_api.c index 84c4ae189..ff67f0205 100644 --- a/src/gns/gns_api.c +++ b/src/gns/gns_api.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - Copyright (C) 2009-2013, 2016 GNUnet e.V. + 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 @@ -31,7 +31,7 @@ #include "gnunet_protocols.h" #include "gnunet_dht_service.h" #include "gns.h" -#include "gnunet_gns_service.h" +#include "gns_api.h" #define LOG(kind,...) GNUNET_log_from (kind, "gns-api",__VA_ARGS__) @@ -80,50 +80,6 @@ struct GNUNET_GNS_LookupRequest }; -/** - * Connection to the GNS service. - */ -struct GNUNET_GNS_Handle -{ - - /** - * Configuration to use. - */ - const struct GNUNET_CONFIGURATION_Handle *cfg; - - /** - * Connection to service (if available). - */ - struct GNUNET_MQ_Handle *mq; - - /** - * Head of linked list of active lookup requests. - */ - struct GNUNET_GNS_LookupRequest *lookup_head; - - /** - * Tail of linked list of active lookup requests. - */ - struct GNUNET_GNS_LookupRequest *lookup_tail; - - /** - * Reconnect task - */ - struct GNUNET_SCHEDULER_Task *reconnect_task; - - /** - * How long do we wait until we try to reconnect? - */ - struct GNUNET_TIME_Relative reconnect_backoff; - - /** - * Request Id generator. Incremented by one for each request. - */ - uint32_t r_id_gen; - -}; - - /** * Reconnect to GNS service. * @@ -201,7 +157,8 @@ check_result (void *cls, size_t mlen = ntohs (lookup_msg->header.size) - sizeof (*lookup_msg); uint32_t rd_count = ntohl (lookup_msg->rd_count); struct GNUNET_GNSRECORD_Data rd[rd_count]; - + + (void) cls; if (GNUNET_SYSERR == GNUNET_GNSRECORD_records_deserialize (mlen, (const char*) &lookup_msg[1], @@ -423,4 +380,5 @@ GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle, return lr; } + /* end of gns_api.c */ diff --git a/src/gns/gnunet-gns.c b/src/gns/gnunet-gns.c index 202e02a50..32cfba5bb 100644 --- a/src/gns/gnunet-gns.c +++ b/src/gns/gnunet-gns.c @@ -25,7 +25,6 @@ #include "platform.h" #include #include -#include #include #include #include @@ -40,11 +39,6 @@ static const struct GNUNET_CONFIGURATION_Handle *cfg; */ static struct GNUNET_GNS_Handle *gns; -/** - * Desired timeout for the lookup (default is no timeout). - */ -static struct GNUNET_TIME_Relative timeout; - /** * GNS name to lookup. (-u option) */ @@ -66,41 +60,20 @@ static enum GNUNET_GNS_LocalOptions local_options; static int raw; /** - * Requested record type. + * Desired record type. */ -static int rtype; +static uint32_t rtype; /** * Handle to lookup request */ -static struct GNUNET_GNS_LookupRequest *lookup_request; - -/** - * Lookup an ego with the identity service. - */ -static struct GNUNET_IDENTITY_EgoLookup *el; - -/** - * Handle for identity service. - */ -static struct GNUNET_IDENTITY_Handle *identity; - -/** - * Active operation on identity service. - */ -static struct GNUNET_IDENTITY_Operation *id_op; - -/** - * Task scheduled to handle timeout. - */ -static struct GNUNET_SCHEDULER_Task *tt; +static struct GNUNET_GNS_LookupWithTldRequest *lr; /** * Global return value. * 0 on success (default), * 1 on internal failures, 2 on launch failure, * 3 if the name is not a GNS-supported TLD, - * 4 on timeout */ static int global_ret; @@ -113,50 +86,17 @@ static int global_ret; static void do_shutdown (void *cls) { - if (NULL != el) + (void) cls; + if (NULL != lr) { - GNUNET_IDENTITY_ego_lookup_cancel (el); - el = NULL; - } - if (NULL != id_op) - { - GNUNET_IDENTITY_cancel (id_op); - id_op = NULL; - } - if (NULL != lookup_request) - { - GNUNET_GNS_lookup_cancel (lookup_request); - lookup_request = NULL; - } - if (NULL != identity) - { - GNUNET_IDENTITY_disconnect (identity); - identity = NULL; + GNUNET_GNS_lookup_with_tld_cancel (lr); + lr = NULL; } if (NULL != gns) { GNUNET_GNS_disconnect (gns); gns = NULL; } - if (NULL != tt) - { - GNUNET_SCHEDULER_cancel (tt); - tt = NULL; - } -} - - -/** - * Task run on timeout. Triggers shutdown. - * - * @param cls unused - */ -static void -do_timeout (void *cls) -{ - tt = NULL; - GNUNET_SCHEDULER_shutdown (); - global_ret = 4; } @@ -164,11 +104,13 @@ do_timeout (void *cls) * Function called with the result of a GNS lookup. * * @param cls the 'const char *' name that was resolved + * @param was_gns #GNUNET_NO if TLD did not indicate use of GNS * @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, + int was_gns, uint32_t rd_count, const struct GNUNET_GNSRECORD_Data *rd) { @@ -176,8 +118,14 @@ process_lookup_result (void *cls, const char *typename; char* string_val; - lookup_request = NULL; - if (!raw) + lr = NULL; + if (GNUNET_NO == was_gns) + { + global_ret = 3; + GNUNET_SCHEDULER_shutdown (); + return; + } + if (! raw) { if (0 == rd_count) printf ("No results.\n"); @@ -215,117 +163,6 @@ process_lookup_result (void *cls, } -/** - * Perform the actual resolution, starting with the zone - * identified by the given public key and the shorten zone. - * - * @param pkey public key to use for the zone, can be NULL - */ -static void -lookup_with_public_key (const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey) -{ - if (NULL != lookup_type) - rtype = GNUNET_GNSRECORD_typename_to_number (lookup_type); - else - rtype = GNUNET_DNSPARSER_TYPE_A; - if (UINT32_MAX == rtype) - { - fprintf (stderr, - _("Invalid typename specified, assuming `ANY'\n")); - rtype = GNUNET_GNSRECORD_TYPE_ANY; - } - - if (NULL != lookup_name) - { - lookup_request = GNUNET_GNS_lookup (gns, - lookup_name, - pkey, - rtype, - local_options, - &process_lookup_result, - lookup_name); - } - else - { - fprintf (stderr, - _("Please specify name to lookup!\n")); - GNUNET_SCHEDULER_shutdown (); - return; - } -} - - -/** - * Method called to with the ego we are to use for the lookup, - * when the ego is determined by a name. - * - * @param cls closure (NULL, unused) - * @param ego ego handle, NULL if not found - */ -static void -identity_zone_cb (void *cls, - const struct GNUNET_IDENTITY_Ego *ego) -{ - struct GNUNET_CRYPTO_EcdsaPublicKey pkey; - - el = NULL; - if (NULL == ego) - { - global_ret = 3; /* Not a GNS TLD */ - GNUNET_SCHEDULER_shutdown (); - } - else - { - GNUNET_IDENTITY_ego_get_public_key (ego, - &pkey); - lookup_with_public_key (&pkey); - } -} - - -/** - * 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'; -} - - /** * Main function that will be run. * @@ -340,82 +177,45 @@ run (void *cls, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c) { - struct GNUNET_CRYPTO_EcdsaPublicKey pkey; - const char *tld; - char *dot_tld; - char *zonestr; - + (void) cls; + (void) args; + (void) cfgfile; + cfg = c; gns = GNUNET_GNS_connect (cfg); if (NULL == gns) { fprintf (stderr, _("Failed to connect to GNS\n")); + global_ret = 2; return; } - tt = GNUNET_SCHEDULER_add_delayed (timeout, - &do_timeout, - NULL); + GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL); - /* start with trivial case: TLD is zkey */ - tld = get_tld (lookup_name); - if (GNUNET_OK == - GNUNET_CRYPTO_ecdsa_public_key_from_string (tld, - strlen (tld), - &pkey)) + + if (NULL != lookup_type) + rtype = GNUNET_GNSRECORD_typename_to_number (lookup_type); + else + rtype = GNUNET_DNSPARSER_TYPE_A; + if (UINT32_MAX == rtype) { - eat_tld (lookup_name); - lookup_with_public_key (&pkey); - return; + fprintf (stderr, + _("Invalid typename specified, assuming `ANY'\n")); + rtype = GNUNET_GNSRECORD_TYPE_ANY; } - - /* second case: TLD is mapped in our configuration file */ - GNUNET_asprintf (&dot_tld, - ".%s", - tld); - if (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_string (cfg, - "gns", - dot_tld, - &zonestr)) + lr = GNUNET_GNS_lookup_with_tld (gns, + lookup_name, + rtype, + local_options, + &process_lookup_result, + NULL); + if (NULL == lr) { - 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_SCHEDULER_shutdown (); - return; - } - GNUNET_free (dot_tld); - GNUNET_free (zonestr); - eat_tld (lookup_name); - lookup_with_public_key (&pkey); + global_ret = 2; + GNUNET_SCHEDULER_shutdown (); return; - } - GNUNET_free (dot_tld); - - /* Final case: TLD matches one of our egos */ - eat_tld (lookup_name); - - /* if the name is of the form 'label.gnu', never go to the DHT */ - if (NULL == strchr (lookup_name, - (unsigned char) '.')) - local_options = GNUNET_GNS_LO_NO_DHT; - identity = GNUNET_IDENTITY_connect (cfg, - NULL, - NULL); - el = GNUNET_IDENTITY_ego_lookup (cfg, - tld, - &identity_zone_cb, - NULL); + } } @@ -442,11 +242,6 @@ main (int argc, "TYPE", gettext_noop ("Specify the type of the record to lookup"), &lookup_type), - GNUNET_GETOPT_option_relative_time ('T', - "timeout", - "DELAY", - gettext_noop ("Specify timeout for the lookup"), - &timeout), GNUNET_GETOPT_option_flag ('r', "raw", gettext_noop ("No unneeded output"), @@ -455,7 +250,6 @@ main (int argc, }; int ret; - timeout = GNUNET_TIME_UNIT_FOREVER_REL; if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) diff --git a/src/include/gnunet_gns_service.h b/src/include/gnunet_gns_service.h index 2ef946a82..1eb67ed50 100644 --- a/src/include/gnunet_gns_service.h +++ b/src/include/gnunet_gns_service.h @@ -66,6 +66,12 @@ struct GNUNET_GNS_Handle; */ struct GNUNET_GNS_LookupRequest; +/** + * Handle to control a lookup operation where the + * TLD is resolved to a zone as part of the lookup operation. + */ +struct GNUNET_GNS_LookupWithTldRequest; + /** * Initialize the connection with the GNS service. @@ -154,6 +160,54 @@ void GNUNET_GNS_lookup_cancel (struct GNUNET_GNS_LookupRequest *lr); +/** + * Iterator called on obtained result for a GNS lookup + * where "not GNS" is a valid answer. + * + * @param cls closure + * @param gns_tld #GNUNET_YES if a GNS lookup was attempted, + * #GNUNET_NO if the TLD is not configured for GNS + * @param rd_count number of records in @a rd + * @param rd the records in the reply + */ +typedef void +(*GNUNET_GNS_LookupResultProcessor2) (void *cls, + int gns_tld, + uint32_t rd_count, + const struct GNUNET_GNSRECORD_Data *rd); + + +/** + * 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 + */ +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); + + +/** + * Cancel pending lookup request + * + * @param ltr the lookup request to cancel + */ +void +GNUNET_GNS_lookup_with_tld_cancel (struct GNUNET_GNS_LookupWithTldRequest *ltr); + + #if 0 /* keep Emacsens' auto-indent happy */ { #endif -- 2.25.1