From 92a2b1758aa56383360603567c17646a1a7fb443 Mon Sep 17 00:00:00 2001 From: "Schanzenbach, Martin" Date: Thu, 27 Jun 2019 09:08:06 +0200 Subject: [PATCH] fix #5782 --- src/gns/gnunet-gns.c | 36 ++++++++++++++ src/gns/nss/nss_gns_query.c | 99 ++++++++++++++++--------------------- 2 files changed, 79 insertions(+), 56 deletions(-) diff --git a/src/gns/gnunet-gns.c b/src/gns/gnunet-gns.c index 1cda84c59..d795f89fc 100644 --- a/src/gns/gnunet-gns.c +++ b/src/gns/gnunet-gns.c @@ -59,6 +59,16 @@ static int raw; */ static uint32_t rtype; +/** + * Timeout for lookup + */ +static struct GNUNET_TIME_Relative timeout; + +/** + * Timeout task + */ +static struct GNUNET_SCHEDULER_Task *to_task; + /** * Handle to lookup request */ @@ -83,6 +93,11 @@ static void do_shutdown (void *cls) { (void) cls; + if (NULL != to_task) + { + GNUNET_SCHEDULER_cancel (to_task); + to_task = NULL; + } if (NULL != lr) { GNUNET_GNS_lookup_with_tld_cancel (lr); @@ -95,6 +110,18 @@ do_shutdown (void *cls) } } +/** + * Task to run on timeout + * + * @param cls unused + */ +static void +do_timeout (void* cls) +{ + to_task = NULL; + global_ret = 3; //Timeout + GNUNET_SCHEDULER_shutdown (); +} /** * Function called with the result of a GNS lookup. @@ -173,12 +200,14 @@ run (void *cls, (void) cfgfile; cfg = c; + to_task = NULL; if (GNUNET_OK != GNUNET_DNSPARSER_check_name (lookup_name)) { fprintf (stderr, _ ("`%s' is not a valid domain name\n"), lookup_name); global_ret = 3; return; } + to_task = GNUNET_SCHEDULER_add_delayed (timeout, &do_timeout, NULL); gns = GNUNET_GNS_connect (cfg); if (NULL == gns) { @@ -221,6 +250,7 @@ run (void *cls, int main (int argc, char *const *argv) { + timeout = GNUNET_TIME_UNIT_FOREVER_REL; struct GNUNET_GETOPT_CommandLineOption options[] = {GNUNET_GETOPT_option_mandatory ( GNUNET_GETOPT_option_string ('u', @@ -235,6 +265,12 @@ main (int argc, char *const *argv) gettext_noop ( "Specify the type of the record to lookup"), &lookup_type), + GNUNET_GETOPT_option_relative_time ('T', + "timeout", + "TIMEOUT", + gettext_noop ( + "Specify a timeout for the lookup"), + &timeout), GNUNET_GETOPT_option_flag ('r', "raw", gettext_noop ("No unneeded output"), diff --git a/src/gns/nss/nss_gns_query.c b/src/gns/nss/nss_gns_query.c index 380788d35..253bb0f02 100644 --- a/src/gns/nss/nss_gns_query.c +++ b/src/gns/nss/nss_gns_query.c @@ -30,6 +30,7 @@ #include #include +#define TIMEOUT "5s" static void kwait (pid_t chld) @@ -37,9 +38,7 @@ kwait (pid_t chld) int ret; kill (chld, SIGKILL); - waitpid (chld, - &ret, - 0); + waitpid (chld, &ret, 0); } @@ -56,9 +55,7 @@ kwait (pid_t chld) * else 0 */ int -gns_resolve_name (int af, - const char *name, - struct userdata *u) +gns_resolve_name (int af, const char *name, struct userdata *u) { FILE *p; char line[128]; @@ -73,88 +70,78 @@ gns_resolve_name (int af, return -1; if (0 == pid) { - char *argv[] = { - "gnunet-gns", - "-r", - "-t", - (AF_INET6 == af) ? "AAAA" : "A", - "-u", - (char *) name, - NULL - }; + char *argv[] = {"gnunet-gns", + "-r", + "-t", + (AF_INET6 == af) ? "AAAA" : "A", + "-u", + (char *) name, + "-T", + TIMEOUT, + NULL}; (void) close (STDOUT_FILENO); - if ( (0 != close (out[0])) || - (STDOUT_FILENO != dup2 (out[1], STDOUT_FILENO)) ) + if ((0 != close (out[0])) || + (STDOUT_FILENO != dup2 (out[1], STDOUT_FILENO))) _exit (1); - (void) execvp ("gnunet-gns", - argv); + (void) execvp ("gnunet-gns", argv); _exit (1); } (void) close (out[1]); p = fdopen (out[0], "r"); if (NULL == p) - { - kwait (pid); - return -1; - } - while (NULL != fgets (line, - sizeof (line), - p)) + { + kwait (pid); + return -1; + } + while (NULL != fgets (line, sizeof (line), p)) { if (u->count >= MAX_ENTRIES) break; - if (line[strlen(line)-1] == '\n') + if (line[strlen (line) - 1] == '\n') { - line[strlen(line)-1] = '\0'; + line[strlen (line) - 1] = '\0'; if (AF_INET == af) { - if (inet_pton(af, - line, - &u->data.ipv4[u->count])) + if (inet_pton (af, line, &u->data.ipv4[u->count])) + { + u->count++; + u->data_len += sizeof (ipv4_address_t); + } + else { - u->count++; - u->data_len += sizeof(ipv4_address_t); - } - else - { - (void) fclose (p); + (void) fclose (p); kwait (pid); - errno = EINVAL; - return -1; - } + errno = EINVAL; + return -1; + } } else if (AF_INET6 == af) { - if (inet_pton(af, - line, - &u->data.ipv6[u->count])) + if (inet_pton (af, line, &u->data.ipv6[u->count])) { - u->count++; - u->data_len += sizeof(ipv6_address_t); - } - else + u->count++; + u->data_len += sizeof (ipv6_address_t); + } + else { - (void) fclose (p); + (void) fclose (p); kwait (pid); - errno = EINVAL; - return -1; - } + errno = EINVAL; + return -1; + } } } } (void) fclose (p); - waitpid (pid, - &ret, - 0); + waitpid (pid, &ret, 0); if (! WIFEXITED (ret)) return -1; if (4 == WEXITSTATUS (ret)) return -2; /* not for GNS */ if (3 == ret) return -3; /* timeout -> not found */ - if ( (2 == WEXITSTATUS (ret)) || - (1 == WEXITSTATUS (ret)) ) + if ((2 == WEXITSTATUS (ret)) || (1 == WEXITSTATUS (ret))) return -2; /* launch failure -> service unavailable */ return 0; } -- 2.25.1