[git] GnuPG - branch, master, updated. gnupg-2.1.21-41-g9b43220

by Werner Koch cvs at cvs.gnupg.org
Thu Jun 8 09:51:14 CEST 2017


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The GNU Privacy Guard".

The branch, master has been updated
       via  9b43220b8ad1a5c1cd51de3bbfff7ccbcc3fa877 (commit)
       via  5b9025cfa1f9b1c67ddf2f6bf87d863e780cf157 (commit)
       via  17e5afd80f247c356f03c71e8b61da424ffedabb (commit)
      from  e051e396156211449568afa0ca7505dc13eaa3b4 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 9b43220b8ad1a5c1cd51de3bbfff7ccbcc3fa877
Author: Werner Koch <wk at gnupg.org>
Date:   Thu Jun 8 09:30:48 2017 +0200

    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 <wk at gnupg.org>

diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c
index 8393e0b..6eabca9 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 e10de09..0f5dde2 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 f56a9ff..e53a0ee 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 ddb8549..bcdcffa 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 02269da..95fa34c 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 237cb52..151f1a0 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 22a7943..64b24f9 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}
+ at opindex resolver-timeout
 Set the timeout for the DNS resolver to N seconds.  The default are 30
 seconds.
 
+ at item --connect-timeout @var{n}
+ at item --connect-quick-timeout @var{n}
+ at opindex connect-timeout
+ at 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

commit 5b9025cfa1f9b1c67ddf2f6bf87d863e780cf157
Author: Werner Koch <wk at gnupg.org>
Date:   Thu Jun 8 08:23:06 2017 +0200

    dirmngr: Allow a timeout for HTTP and other TCP connects.
    
    * dirmngr/http.c: Include fcntl.h.
    (http_session_s): Add field 'connect_timeout'.
    (http_session_new): Clear that.
    (http_session_set_timeout): New function.
    (my_wsagetlasterror) [W32]: New.
    (connect_with_timeout): New function.
    (connect_server): Add arg 'timeout' and call connect_with_timeout.
    (send_request): Add arg 'timeout' and pass it to connect_server.
    (http_raw_connect): Add arg 'timeout'.
    (http_open): Pass TIMEOUT from the session to connect_server.
    --
    
    Note that the non-blocking connect we implement is traditional a
    pretty non-portable thing due to slighly different semantics.  The
    code uses the strategy W. Richard Stevens suggested in 1998.
    Hopefully current OS versions got it all right.
    
    The code has not been tested on Windows.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/dirmngr/http.c b/dirmngr/http.c
index f461e5d..0544c9b 100644
--- a/dirmngr/http.c
+++ b/dirmngr/http.c
@@ -70,6 +70,7 @@
 # include <sys/socket.h>
 # include <sys/time.h>
 # include <time.h>
+# include <fcntl.h>
 # include <netinet/in.h>
 # include <arpa/inet.h>
 # include <netdb.h>
@@ -153,13 +154,14 @@ static int insert_escapes (char *buffer, const char *string,
 static uri_tuple_t parse_tuple (char *string);
 static gpg_error_t send_request (http_t hd, const char *httphost,
                                  const char *auth,const char *proxy,
-				 const char *srvtag,strlist_t headers);
+				 const char *srvtag, unsigned int timeout,
+                                 strlist_t headers);
 static char *build_rel_path (parsed_uri_t uri);
 static gpg_error_t parse_response (http_t hd);
 
 static gpg_error_t connect_server (const char *server, unsigned short port,
                                    unsigned int flags, const char *srvtag,
-                                   assuan_fd_t *r_sock);
+                                   unsigned int timeout, assuan_fd_t *r_sock);
 static gpgrt_ssize_t read_server (assuan_fd_t sock, void *buffer, size_t size);
 static gpg_error_t write_server (assuan_fd_t sock, const char *data, size_t length);
 
@@ -259,6 +261,9 @@ struct http_session_s
   /* A per-session TLS verification callback.  */
   http_verify_cb_t verify_cb;
   void *verify_cb_value;
+
+  /* The connect timeout */
+  unsigned int connect_timeout;
 };
 
 
@@ -695,6 +700,7 @@ http_session_new (http_session_t *r_session,
   sess->flags = flags;
   sess->verify_cb = verify_cb;
   sess->verify_cb_value = verify_cb_value;
+  sess->connect_timeout = 0;
 
 #if HTTP_USE_NTBTLS
   {
@@ -867,6 +873,15 @@ http_session_set_log_cb (http_session_t sess,
 }
 
 
+/* Set the TIMEOUT in milliseconds for the connection's connect
+ * calls.  Using 0 disables the timeout.  */
+void
+http_session_set_timeout (http_session_t sess, unsigned int timeout)
+{
+  sess->connect_timeout = timeout;
+}
+
+
 
 

 /* Start a HTTP retrieval and on success store at R_HD a context
@@ -898,7 +913,9 @@ http_open (http_t *r_hd, http_req_t reqtype, const char *url,
 
   err = parse_uri (&hd->uri, url, 0, !!(flags & HTTP_FLAG_FORCE_TLS));
   if (!err)
-    err = send_request (hd, httphost, auth, proxy, srvtag, headers);
+    err = send_request (hd, httphost, auth, proxy, srvtag,
+                        hd->session? hd->session->connect_timeout : 0,
+                        headers);
 
   if (err)
     {
@@ -918,10 +935,10 @@ http_open (http_t *r_hd, http_req_t reqtype, const char *url,
 
 /* This function is useful to connect to a generic TCP service using
    this http abstraction layer.  This has the advantage of providing
-   service tags and an estream interface.  */
+   service tags and an estream interface.  TIMEOUT is in milliseconds. */
 gpg_error_t
 http_raw_connect (http_t *r_hd, const char *server, unsigned short port,
-                  unsigned int flags, const char *srvtag)
+                  unsigned int flags, const char *srvtag, unsigned int timeout)
 {
   gpg_error_t err = 0;
   http_t hd;
@@ -952,7 +969,7 @@ http_raw_connect (http_t *r_hd, const char *server, unsigned short port,
   {
     assuan_fd_t sock;
 
-    err = connect_server (server, port, hd->flags, srvtag, &sock);
+    err = connect_server (server, port, hd->flags, srvtag, timeout, &sock);
     if (err)
       {
         xfree (hd);
@@ -1635,7 +1652,8 @@ is_hostname_port (const char *string)
  */
 static gpg_error_t
 send_request (http_t hd, const char *httphost, const char *auth,
-	      const char *proxy, const char *srvtag, strlist_t headers)
+	      const char *proxy, const char *srvtag, unsigned int timeout,
+              strlist_t headers)
 {
   gpg_error_t err;
   const char *server;
@@ -1762,12 +1780,12 @@ send_request (http_t hd, const char *httphost, const char *auth,
 
       err = connect_server (*uri->host ? uri->host : "localhost",
                             uri->port ? uri->port : 80,
-                            hd->flags, srvtag, &sock);
+                            hd->flags, srvtag, timeout, &sock);
       http_release_parsed_uri (uri);
     }
   else
     {
-      err = connect_server (server, port, hd->flags, srvtag, &sock);
+      err = connect_server (server, port, hd->flags, srvtag, timeout, &sock);
     }
 
   if (err)
@@ -2526,13 +2544,162 @@ my_sock_new_for_addr (struct sockaddr_storage *addr, int type, int proto)
 }
 
 
+/* Call WSAGetLastError and map it to a libgpg-error.  */
+#ifdef HAVE_W32_SYSTEM
+static gpg_error_t
+my_wsagetlasterror (void)
+{
+  int wsaerr;
+  gpg_err_code_t ec;
+
+  wsaerr = WSAGetLastError ();
+  switch (wsaerr)
+    {
+    case WSAENOTSOCK:        ec = GPG_ERR_EINVAL;       break;
+    case WSAEWOULDBLOCK:     ec = GPG_ERR_EAGAIN;       break;
+    case ERROR_BROKEN_PIPE:  ec = GPG_ERR_EPIPE;        break;
+    case WSANOTINITIALISED:  ec = GPG_ERR_ENOSYS;       break;
+    case WSAENOBUFS:         ec = GPG_ERR_ENOBUFS;      break;
+    case WSAEMSGSIZE:        ec = GPG_ERR_EMSGSIZE;     break;
+    case WSAECONNREFUSED:    ec = GPG_ERR_ECONNREFUSED; break;
+    case WSAEISCONN:         ec = GPG_ERR_EISCONN;      break;
+    case WSAEALREADY:        ec = GPG_ERR_EALREADY;     break;
+    case WSAETIMEDOUT:       ec = GPG_ERR_ETIMEDOUT;    break;
+    default:                 ec = GPG_ERR_EIO;          break;
+    }
+
+  return gpg_err_make (default_errsource, ec);
+}
+#endif /*HAVE_W32_SYSTEM*/
+
+
+/* Connect SOCK and return GPG_ERR_ETIMEOUT if a connection could not
+ * be established within TIMEOUT milliseconds.  0 indicates the
+ * system's default timeout.  The other args are the usual connect
+ * args.  On success 0 is returned, on timeout GPG_ERR_ETIMEDOUT, and
+ * another error code for other errors.  On timeout the caller needs
+ * to close the socket as soon as possible to stop an ongoing
+ * handshake.
+ *
+ * This implementation is for well-behaving systems; see Stevens,
+ * Network Programming, 2nd edition, Vol 1, 15.4.  */
+static gpg_error_t
+connect_with_timeout (assuan_fd_t sock,
+                      struct sockaddr *addr, int addrlen,
+                      unsigned int timeout)
+{
+  gpg_error_t err;
+  int syserr;
+  socklen_t slen;
+  fd_set rset, wset;
+  struct timeval tval;
+  int n;
+
+#ifndef HAVE_W32_SYSTEM
+  int oflags;
+# define RESTORE_BLOCKING()  do {  \
+    fcntl (sock, F_SETFL, oflags); \
+  } while (0)
+#else /*HAVE_W32_SYSTEM*/
+# define RESTORE_BLOCKING()  do {                       \
+    unsigned long along = 0;                            \
+    ioctlsocket (FD2INT (sock), FIONBIO, &along);       \
+  } while (0)
+#endif /*HAVE_W32_SYSTEM*/
+
+
+  if (!timeout)
+    {
+      /* Shortcut.  */
+      if (assuan_sock_connect (sock, addr, addrlen))
+        err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
+      else
+        err = 0;
+      return err;
+    }
+
+  /* Switch the socket into non-blocking mode.  */
+#ifdef HAVE_W32_SYSTEM
+  {
+    unsigned long along = 1;
+    if (ioctlsocket (FD2INT (sock), FIONBIO, &along))
+      return my_wsagetlasterror ();
+  }
+#else
+  oflags = fcntl (sock, F_GETFL, 0);
+  if (fcntl (sock, F_SETFL, oflags | O_NONBLOCK))
+    return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
+#endif
+
+  /* Do the connect.  */
+  if (!assuan_sock_connect (sock, addr, addrlen))
+    {
+      /* Immediate connect.  Restore flags. */
+      RESTORE_BLOCKING ();
+      return 0; /* Success.  */
+    }
+  err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
+  if (gpg_err_code (err) != GPG_ERR_EINPROGRESS)
+    {
+      RESTORE_BLOCKING ();
+      return err;
+    }
+
+  FD_ZERO (&rset);
+  FD_SET (sock, &rset);
+  wset = rset;
+  tval.tv_sec = timeout / 1000;
+  tval.tv_usec = (timeout % 1000) * 1000;
+
+  n = my_select (FD2INT(sock)+1, &rset, &wset, NULL, &tval);
+  if (n < 0)
+    {
+      err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
+      RESTORE_BLOCKING ();
+      return err;
+    }
+  if (!n)
+    {
+      /* Timeout: We do not restore the socket flags on timeout
+       * because the caller is expected to close the socket.  */
+      return gpg_err_make (default_errsource, GPG_ERR_ETIMEDOUT);
+    }
+  if (!FD_ISSET (sock, &rset) && !FD_ISSET (sock, &wset))
+    {
+      /* select misbehaved.  */
+      return gpg_err_make (default_errsource, GPG_ERR_SYSTEM_BUG);
+    }
+
+  slen = sizeof (syserr);
+  if (getsockopt (FD2INT(sock), SOL_SOCKET, SO_ERROR,
+                  (void*)&syserr, &slen) < 0)
+    {
+      /* Assume that this is Solaris which returns the error in ERRNO.  */
+      err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
+    }
+  else if (syserr)
+    err = gpg_err_make (default_errsource, gpg_err_code_from_errno (syserr));
+  else
+    err = 0; /* Connected.  */
+
+  RESTORE_BLOCKING ();
+
+  return err;
+
+#undef RESTORE_BLOCKING
+}
+
+
 /* Actually connect to a server.  On success 0 is returned and the
  * file descriptor for the socket is stored at R_SOCK; on error an
- * error code is returned and ASSUAN_INVALID_FD is stored at
- * R_SOCK.  */
+ * error code is returned and ASSUAN_INVALID_FD is stored at R_SOCK.
+ * TIMEOUT is the connect timeout in milliseconds.  Note that the
+ * function tries to connect to all known addresses and the timeout is
+ * for each one. */
 static gpg_error_t
 connect_server (const char *server, unsigned short port,
-                unsigned int flags, const char *srvtag, assuan_fd_t *r_sock)
+                unsigned int flags, const char *srvtag, unsigned int timeout,
+                assuan_fd_t *r_sock)
 {
   gpg_error_t err;
   assuan_fd_t sock = ASSUAN_INVALID_FD;
@@ -2645,11 +2812,11 @@ connect_server (const char *server, unsigned short port,
             }
 
           anyhostaddr = 1;
-          if (assuan_sock_connect (sock, (struct sockaddr *)ai->addr,
-                                   ai->addrlen))
+          err = connect_with_timeout (sock, (struct sockaddr *)ai->addr,
+                                      ai->addrlen, timeout);
+          if (err)
             {
-              last_err = gpg_err_make (default_errsource,
-                                       gpg_err_code_from_syserror ());
+              last_err = err;
             }
           else
             {
diff --git a/dirmngr/http.h b/dirmngr/http.h
index 2609b9e..448cd04 100644
--- a/dirmngr/http.h
+++ b/dirmngr/http.h
@@ -124,6 +124,7 @@ void http_session_set_log_cb (http_session_t sess,
                               void (*cb)(http_session_t, gpg_error_t,
                                          const char *,
                                          const void **, size_t *));
+void http_session_set_timeout (http_session_t sess, unsigned int timeout);
 
 
 gpg_error_t http_parse_uri (parsed_uri_t *ret_uri, const char *uri,
@@ -133,7 +134,8 @@ void http_release_parsed_uri (parsed_uri_t uri);
 
 gpg_error_t http_raw_connect (http_t *r_hd,
                               const char *server, unsigned short port,
-                              unsigned int flags, const char *srvtag);
+                              unsigned int flags, const char *srvtag,
+                              unsigned int timeout);
 
 gpg_error_t http_open (http_t *r_hd, http_req_t reqtype,
                        const char *url,
diff --git a/dirmngr/t-http.c b/dirmngr/t-http.c
index a3a74dd..b0f2bcf 100644
--- a/dirmngr/t-http.c
+++ b/dirmngr/t-http.c
@@ -203,6 +203,7 @@ main (int argc, char **argv)
   int no_crl = 0;
   const char *cafile = NULL;
   http_session_t session = NULL;
+  unsigned int timeout = 0;
 
   gpgrt_init ();
   log_set_prefix (PGM, GPGRT_LOG_WITH_PREFIX | GPGRT_LOG_WITH_PID);
@@ -224,6 +225,7 @@ main (int argc, char **argv)
                  "  --debug           flyswatter\n"
                  "  --tls-debug N     use TLS debug level N\n"
                  "  --cacert FNAME    expect CA certificate in file FNAME\n"
+                 "  --timeout MS      timeout for connect in MS\n"
                  "  --no-verify       do not verify the certificate\n"
                  "  --force-tls       use HTTP_FLAG_FORCE_TLS\n"
                  "  --force-tor       use HTTP_FLAG_FORCE_TOR\n"
@@ -261,6 +263,15 @@ main (int argc, char **argv)
               argc--; argv++;
             }
         }
+      else if (!strcmp (*argv, "--timeout"))
+        {
+          argc--; argv++;
+          if (argc)
+            {
+              timeout = strtoul (*argv, NULL, 10);
+              argc--; argv++;
+            }
+        }
       else if (!strcmp (*argv, "--no-verify"))
         {
           no_verify = 1;
@@ -407,6 +418,9 @@ main (int argc, char **argv)
   http_release_parsed_uri (uri);
   uri = NULL;
 
+  if (session)
+    http_session_set_timeout (session, timeout);
+
   rc = http_open_document (&hd, *argv, NULL, my_http_flags,
                            NULL, session, NULL, NULL);
   if (rc)

commit 17e5afd80f247c356f03c71e8b61da424ffedabb
Author: Werner Koch <wk at gnupg.org>
Date:   Mon Jun 5 11:57:02 2017 +0200

    gpg: Avoid failure exit when scdaemon is disabled but not needed.
    
    * g10/call-agent.c (warn_version_mismatch): Use log_info if error is
    "not supported".
    --
    
    This fix may make the fix for
    GnuPG-bug-id: 3192
    even more robust.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/g10/call-agent.c b/g10/call-agent.c
index e6dbb73..7b76933 100644
--- a/g10/call-agent.c
+++ b/g10/call-agent.c
@@ -194,8 +194,10 @@ warn_version_mismatch (assuan_context_t ctx, const char *servername, int mode)
 
   err = get_assuan_server_version (ctx, mode, &serverversion);
   if (err)
-    log_error (_("error getting version from '%s': %s\n"),
-               servername, gpg_strerror (err));
+    log_log (gpg_err_code (err) == GPG_ERR_NOT_SUPPORTED?
+             GPGRT_LOG_INFO : GPGRT_LOG_ERROR,
+             _("error getting version from '%s': %s\n"),
+             servername, gpg_strerror (err));
   else if (compare_version_strings (serverversion, myversion) < 0)
     {
       char *warn;

-----------------------------------------------------------------------

Summary of changes:
 dirmngr/dirmngr.c          |  43 +++++++++-
 dirmngr/dirmngr.h          |   6 ++
 dirmngr/http.c             | 199 +++++++++++++++++++++++++++++++++++++++++----
 dirmngr/http.h             |   4 +-
 dirmngr/ks-engine-finger.c |   2 +-
 dirmngr/ks-engine-hkp.c    |   1 +
 dirmngr/ks-engine-http.c   |   1 +
 dirmngr/server.c           |  11 ++-
 dirmngr/t-http.c           |  14 ++++
 doc/dirmngr.texi           |  13 +++
 g10/call-agent.c           |   6 +-
 11 files changed, 273 insertions(+), 27 deletions(-)


hooks/post-receive
-- 
The GNU Privacy Guard
http://git.gnupg.org




More information about the Gnupg-commits mailing list