dirmngr: Implement HTTP connect timeouts of 15 or 2 seconds.
authorWerner Koch <wk@gnupg.org>
Thu, 8 Jun 2017 07:30:48 +0000 (09:30 +0200)
committerWerner Koch <wk@gnupg.org>
Thu, 8 Jun 2017 07:37:36 +0000 (09:37 +0200)
* 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 <wk@gnupg.org>
dirmngr/dirmngr.c
dirmngr/dirmngr.h
dirmngr/ks-engine-finger.c
dirmngr/ks-engine-hkp.c
dirmngr/ks-engine-http.c
dirmngr/server.c
doc/dirmngr.texi

index 8393e0b..6eabca9 100644 (file)
@@ -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 ();
 }
 
 
index e10de09..0f5dde2 100644 (file)
@@ -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.  */
 };
 
index f56a9ff..e53a0ee 100644 (file)
@@ -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);
index ddb8549..bcdcffa 100644 (file)
@@ -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,
index 02269da..95fa34c 100644 (file)
@@ -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,
index 237cb52..151f1a0 100644 (file)
@@ -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?  */
index 22a7943..64b24f9 100644 (file)
@@ -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