From 9b43220b8ad1a5c1cd51de3bbfff7ccbcc3fa877 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 8 Jun 2017 09:30:48 +0200 Subject: [PATCH] dirmngr: Implement HTTP connect timeouts of 15 or 2 seconds. * dirmngr/dirmngr.c (oConnectTimeout, oConnectQuickTimeout): New enums. (opts): New options --connect-timeout and --connect-quick-timeout. (DEFAULT_CONNECT_TIMEOUT): New. (DEFAULT_CONNECT_QUICK_TIMEOUT): New. (parse_rereadable_options): Handle new options. (post_option_parsing): New. Use instead of direct calls to set_debug() and set_tor_mode (). (main): Setup default timeouts. (dirmngr_init_default_ctrl): Set standard connect timeout. * dirmngr/dirmngr.h (opt): New fields connect_timeout and connect_quick_timeout. (server_control_s): New field timeout. * dirmngr/ks-engine-finger.c (ks_finger_fetch): Pass timeout to http_raw_connect. * dirmngr/ks-engine-hkp.c (send_request): Call http_session_set_timeout. * dirmngr/ks-engine-http.c (ks_http_fetch): Ditto. * dirmngr/server.c (cmd_wkd_get, cmd_ks_search, cmd_ks_get) (cmd_ks_fetch): Implement --quick option. -- The standard connect timeouts are way to long so we add a timeout to the connect calls. Also implement the --quick option which is already used by gpg for non-important requests (e.g. looking up a key for verification). Signed-off-by: Werner Koch --- dirmngr/dirmngr.c | 43 ++++++++++++++++++++++++++++++++++---- dirmngr/dirmngr.h | 6 ++++++ dirmngr/ks-engine-finger.c | 2 +- dirmngr/ks-engine-hkp.c | 1 + dirmngr/ks-engine-http.c | 1 + dirmngr/server.c | 11 +++++++--- doc/dirmngr.texi | 13 ++++++++++++ 7 files changed, 69 insertions(+), 8 deletions(-) diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c index 8393e0bf3..6eabca9c3 100644 --- a/dirmngr/dirmngr.c +++ b/dirmngr/dirmngr.c @@ -147,6 +147,8 @@ enum cmd_and_opt_values { oStandardResolver, oRecursiveResolver, oResolverTimeout, + oConnectTimeout, + oConnectQuickTimeout, aTest }; @@ -250,6 +252,8 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_s_n (oStandardResolver, "standard-resolver", "@"), ARGPARSE_s_n (oRecursiveResolver, "recursive-resolver", "@"), ARGPARSE_s_i (oResolverTimeout, "resolver-timeout", "@"), + ARGPARSE_s_i (oConnectTimeout, "connect-timeout", "@"), + ARGPARSE_s_i (oConnectQuickTimeout, "connect-quick-timeout", "@"), ARGPARSE_group (302,N_("@\n(See the \"info\" manual for a complete listing " "of all commands and options)\n")), @@ -277,6 +281,9 @@ static struct debug_flags_s debug_flags [] = #define DEFAULT_MAX_REPLIES 10 #define DEFAULT_LDAP_TIMEOUT 100 /* arbitrary large timeout */ +#define DEFAULT_CONNECT_TIMEOUT (15*1000) /* 15 seconds */ +#define DEFAULT_CONNECT_QUICK_TIMEOUT ( 2*1000) /* 2 seconds */ + /* For the cleanup handler we need to keep track of the socket's name. */ static const char *socket_name; /* If the socket has been redirected, this is the name of the @@ -602,6 +609,8 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread) disable_check_own_socket = 0; enable_standard_resolver (0); set_dns_timeout (0); + opt.connect_timeout = 0; + opt.connect_quick_timeout = 0; return 1; } @@ -703,6 +712,14 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread) set_dns_timeout (pargs->r.ret_int); break; + case oConnectTimeout: + opt.connect_timeout = pargs->r.ret_ulong * 1000; + break; + + case oConnectQuickTimeout: + opt.connect_quick_timeout = pargs->r.ret_ulong * 1000; + break; + default: return 0; /* Not handled. */ } @@ -716,6 +733,21 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread) } +/* This fucntion is called after option parsing to adjust some values + * and call option setup functions. */ +static void +post_option_parsing (void) +{ + /* It would be too surpirsing if the quick timeout is larger than + * the standard value. */ + if (opt.connect_quick_timeout > opt.connect_timeout) + opt.connect_quick_timeout = opt.connect_timeout; + + set_debug (); + set_tor_mode (); +} + + #ifndef HAVE_W32_SYSTEM static int pid_suffix_callback (unsigned long *r_suffix) @@ -844,6 +876,10 @@ main (int argc, char **argv) /* Reset rereadable options to default values. */ parse_rereadable_options (NULL, 0); + /* Default TCP timeouts. */ + opt.connect_timeout = DEFAULT_CONNECT_TIMEOUT; + opt.connect_quick_timeout = DEFAULT_CONNECT_QUICK_TIMEOUT; + /* LDAP defaults. */ opt.add_new_ldapservers = 0; opt.ldaptimeout = DEFAULT_LDAP_TIMEOUT; @@ -1031,8 +1067,7 @@ main (int argc, char **argv) log_printf ("\n"); } - set_debug (); - set_tor_mode (); + post_option_parsing (); /* Get LDAP server list from file. */ #if USE_LDAP @@ -1513,6 +1548,7 @@ dirmngr_init_default_ctrl (ctrl_t ctrl) if (opt.http_proxy) ctrl->http_proxy = xstrdup (opt.http_proxy); ctrl->http_no_crl = 1; + ctrl->timeout = opt.connect_timeout; } @@ -1774,8 +1810,7 @@ reread_configuration (void) } fclose (fp); - set_debug (); - set_tor_mode (); + post_option_parsing (); } diff --git a/dirmngr/dirmngr.h b/dirmngr/dirmngr.h index e10de09c1..0f5dde28e 100644 --- a/dirmngr/dirmngr.h +++ b/dirmngr/dirmngr.h @@ -95,6 +95,10 @@ struct int force; /* Force loading outdated CRLs. */ + + unsigned int connect_timeout; /* Timeout for connect. */ + unsigned int connect_quick_timeout; /* Shorter timeout for connect. */ + int disable_http; /* Do not use HTTP at all. */ int disable_ldap; /* Do not use LDAP at all. */ int disable_ipv4; /* Do not use legacy IP addresses. */ @@ -194,6 +198,8 @@ struct server_control_s int audit_events; /* Send audit events to client. */ char *http_proxy; /* The used http_proxy or NULL. */ + unsigned int timeout; /* Timeout for connect calls in ms. */ + unsigned int http_no_crl:1; /* Do not check CRLs for https. */ }; diff --git a/dirmngr/ks-engine-finger.c b/dirmngr/ks-engine-finger.c index f56a9ff8e..e53a0ee78 100644 --- a/dirmngr/ks-engine-finger.c +++ b/dirmngr/ks-engine-finger.c @@ -86,7 +86,7 @@ ks_finger_fetch (ctrl_t ctrl, parsed_uri_t uri, estream_t *r_fp) ((dirmngr_use_tor ()? HTTP_FLAG_FORCE_TOR : 0) | (opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4 : 0) | (opt.disable_ipv6? HTTP_FLAG_IGNORE_IPv6 : 0)), - NULL); + NULL, ctrl->timeout); if (err) { xfree (name); diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c index ddb854906..bcdcffadd 100644 --- a/dirmngr/ks-engine-hkp.c +++ b/dirmngr/ks-engine-hkp.c @@ -1132,6 +1132,7 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr, if (err) goto leave; http_session_set_log_cb (session, cert_log_cb); + http_session_set_timeout (session, ctrl->timeout); once_more: err = http_open (&http, diff --git a/dirmngr/ks-engine-http.c b/dirmngr/ks-engine-http.c index 02269da6e..95fa34cc1 100644 --- a/dirmngr/ks-engine-http.c +++ b/dirmngr/ks-engine-http.c @@ -83,6 +83,7 @@ ks_http_fetch (ctrl_t ctrl, const char *url, estream_t *r_fp) if (err) goto leave; http_session_set_log_cb (session, cert_log_cb); + http_session_set_timeout (session, ctrl->timeout); *r_fp = NULL; err = http_open (&http, diff --git a/dirmngr/server.c b/dirmngr/server.c index 237cb5278..151f1a063 100644 --- a/dirmngr/server.c +++ b/dirmngr/server.c @@ -842,6 +842,8 @@ cmd_wkd_get (assuan_context_t ctx, char *line) opt_submission_addr = has_option (line, "--submission-address"); opt_policy_flags = has_option (line, "--policy-flags"); + if (has_option (line, "--quick")) + ctrl->timeout = opt.connect_quick_timeout; line = skip_options (line); mbox = mailbox_from_userid (line); @@ -2123,7 +2125,8 @@ cmd_ks_search (assuan_context_t ctx, char *line) char *p; estream_t outfp; - /* No options for now. */ + if (has_option (line, "--quick")) + ctrl->timeout = opt.connect_quick_timeout; line = skip_options (line); /* Break the line down into an strlist. Each pattern is @@ -2187,7 +2190,8 @@ cmd_ks_get (assuan_context_t ctx, char *line) char *p; estream_t outfp; - /* No options for now. */ + if (has_option (line, "--quick")) + ctrl->timeout = opt.connect_quick_timeout; line = skip_options (line); /* Break the line into a strlist. Each pattern is by @@ -2251,7 +2255,8 @@ cmd_ks_fetch (assuan_context_t ctx, char *line) gpg_error_t err; estream_t outfp; - /* No options for now. */ + if (has_option (line, "--quick")) + ctrl->timeout = opt.connect_quick_timeout; line = skip_options (line); err = ensure_keyserver (ctrl); /* FIXME: Why do we needs this here? */ diff --git a/doc/dirmngr.texi b/doc/dirmngr.texi index 22a794316..64b24f9f7 100644 --- a/doc/dirmngr.texi +++ b/doc/dirmngr.texi @@ -260,9 +260,22 @@ Implemented'' if this function is used. When possible use a recursive resolver instead of a stub resolver. @item --resolver-timeout @var{n} +@opindex resolver-timeout Set the timeout for the DNS resolver to N seconds. The default are 30 seconds. +@item --connect-timeout @var{n} +@item --connect-quick-timeout @var{n} +@opindex connect-timeout +@opindex connect-quick-timeout +Set the timeout for HTTP and generic TCP connection attempts to N +seconds. The value set with the quick variant is used when the +--quick option has been given to certain Assuan commands. The quick +value is capped at the value of the regular connect timeout. The +default values are 15 and 2 seconds. Note that the timeout values are +for each connection attempt; the connection code will attempt to +connect all addresses listed for a server. + @item --allow-version-check @opindex allow-version-check Allow Dirmngr to connect to @code{https://versions.gnupg.org} to get