[git] GnuPG - branch, master, updated. gnupg-2.1.0beta3-355-gfb56a27

by Werner Koch cvs at cvs.gnupg.org
Wed Mar 12 14:33:18 CET 2014


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  fb56a273b1f2b3a99dc1d1a0850378ab7625e6b9 (commit)
       via  99135b89ced35d867dddadf9d51e63a3d8837fc3 (commit)
       via  3d9e0eb02ce2b2e153e25deb0fc4b27b45f5026a (commit)
      from  781b94174310dceffa075719420b74b29fe41764 (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 fb56a273b1f2b3a99dc1d1a0850378ab7625e6b9
Author: Werner Koch <wk at gnupg.org>
Date:   Wed Mar 12 14:32:34 2014 +0100

    dirmngr: Detect dead keyservers and try another one.
    
    * dirmngr/ks-action.c (ks_action_resolve): Rename var for clarity.
    (ks_action_search, ks_action_put): Ditto.
    (ks_action_get): Consult only the first server which retruned some
    data.
    
    * dirmngr/ks-engine-hkp.c (SEND_REQUEST_RETRIES): New.
    (map_host): Add arg CTRL and call dirmngr_tick.
    (make_host_part): Add arg CTRL.
    (mark_host_dead): Allow the use of an URL.
    (handle_send_request_error): New.
    (ks_hkp_search, ks_hkp_get, ks_hkp_put): Mark host dead and retry on
    error.

diff --git a/dirmngr/ks-action.c b/dirmngr/ks-action.c
index dfeb862..495f7fa 100644
--- a/dirmngr/ks-action.c
+++ b/dirmngr/ks-action.c
@@ -120,21 +120,21 @@ gpg_error_t
 ks_action_resolve (ctrl_t ctrl)
 {
   gpg_error_t err = 0;
-  int any = 0;
+  int any_server = 0;
   uri_item_t uri;
 
   for (uri = ctrl->keyservers; !err && uri; uri = uri->next)
     {
       if (uri->parsed_uri->is_http)
         {
-          any = 1;
+          any_server = 1;
           err = ks_hkp_resolve (ctrl, uri->parsed_uri);
           if (err)
             break;
         }
     }
 
-  if (!any)
+  if (!any_server)
     err = gpg_error (GPG_ERR_NO_KEYSERVER);
   return err;
 }
@@ -146,7 +146,7 @@ gpg_error_t
 ks_action_search (ctrl_t ctrl, strlist_t patterns, estream_t outfp)
 {
   gpg_error_t err = 0;
-  int any = 0;
+  int any_server = 0;
   uri_item_t uri;
   estream_t infp;
 
@@ -163,7 +163,7 @@ ks_action_search (ctrl_t ctrl, strlist_t patterns, estream_t outfp)
     {
       if (uri->parsed_uri->is_http)
         {
-          any = 1;
+          any_server = 1;
           err = ks_hkp_search (ctrl, uri->parsed_uri, patterns->d, &infp);
           if (!err)
             {
@@ -174,7 +174,7 @@ ks_action_search (ctrl_t ctrl, strlist_t patterns, estream_t outfp)
         }
     }
 
-  if (!any)
+  if (!any_server)
     err = gpg_error (GPG_ERR_NO_KEYSERVER);
   return err;
 }
@@ -187,7 +187,8 @@ ks_action_get (ctrl_t ctrl, strlist_t patterns, estream_t outfp)
 {
   gpg_error_t err = 0;
   gpg_error_t first_err = 0;
-  int any = 0;
+  int any_server = 0;
+  int any_data = 0;
   strlist_t sl;
   uri_item_t uri;
   estream_t infp;
@@ -205,7 +206,7 @@ ks_action_get (ctrl_t ctrl, strlist_t patterns, estream_t outfp)
     {
       if (uri->parsed_uri->is_http)
         {
-          any = 1;
+          any_server = 1;
           for (sl = patterns; !err && sl; sl = sl->next)
             {
               err = ks_hkp_get (ctrl, uri->parsed_uri, sl->d, &infp);
@@ -224,17 +225,21 @@ ks_action_get (ctrl_t ctrl, strlist_t patterns, estream_t outfp)
                   err = copy_stream (infp, outfp);
                   /* Reading from the keyserver should never fail, thus
                      return this error.  */
+                  if (!err)
+                    any_data = 1;
                   es_fclose (infp);
                   infp = NULL;
                 }
             }
         }
+      if (any_data)
+        break; /* Stop loop after a keyserver returned something.  */
     }
 
-  if (!any)
+  if (!any_server)
     err = gpg_error (GPG_ERR_NO_KEYSERVER);
-  else if (!err && first_err)
-    err = first_err; /* fixme: Do we really want to do that?  */
+  else if (!err && first_err && !any_data)
+    err = first_err;
   return err;
 }
 
@@ -302,14 +307,14 @@ ks_action_put (ctrl_t ctrl, const void *data, size_t datalen)
 {
   gpg_error_t err = 0;
   gpg_error_t first_err = 0;
-  int any = 0;
+  int any_server = 0;
   uri_item_t uri;
 
   for (uri = ctrl->keyservers; !err && uri; uri = uri->next)
     {
       if (uri->parsed_uri->is_http)
         {
-          any = 1;
+          any_server = 1;
           err = ks_hkp_put (ctrl, uri->parsed_uri, data, datalen);
           if (err)
             {
@@ -319,9 +324,9 @@ ks_action_put (ctrl_t ctrl, const void *data, size_t datalen)
         }
     }
 
-  if (!any)
+  if (!any_server)
     err = gpg_error (GPG_ERR_NO_KEYSERVER);
   else if (!err && first_err)
-    err = first_err; /* fixme: Do we really want to do that?  */
+    err = first_err;
   return err;
 }
diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c
index 13da3cb..28b05e9 100644
--- a/dirmngr/ks-engine-hkp.c
+++ b/dirmngr/ks-engine-hkp.c
@@ -53,6 +53,9 @@
 /* How many redirections do we allow.  */
 #define MAX_REDIRECTS 2
 
+/* Number of retries done for a dead host etc.  */
+#define SEND_REQUEST_RETRIES 3
+
 /* Objects used to maintain information about hosts.  */
 struct hostinfo_s;
 typedef struct hostinfo_s *hostinfo_t;
@@ -242,7 +245,7 @@ my_getnameinfo (const struct sockaddr *sa, socklen_t salen,
    independent of DNS retry times.  If FORCE_RESELECT is true a new
    host is always selected. */
 static char *
-map_host (const char *name, int force_reselect)
+map_host (ctrl_t ctrl, const char *name, int force_reselect)
 {
   hostinfo_t hi;
   int idx;
@@ -291,6 +294,7 @@ map_host (const char *name, int force_reselect)
               if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
                 continue;
 
+              dirmngr_tick (ctrl);
               if ((ec = my_getnameinfo (ai->ai_addr, ai->ai_addrlen,
                                         tmphost, sizeof tmphost)))
                 {
@@ -401,22 +405,51 @@ map_host (const char *name, int force_reselect)
 }
 
 
-/* Mark the host NAME as dead.  */
-static void
+/* Mark the host NAME as dead.  NAME may be given as an URL.  Returns
+   true if a host was really marked as dead or was already marked dead
+   (e.g. by a concurrent session).  */
+static int
 mark_host_dead (const char *name)
 {
-  hostinfo_t hi;
-  int idx;
+  const char *host;
+  char *host_buffer = NULL;
+  parsed_uri_t parsed_uri = NULL;
+  int done = 0;
 
-  if (!name || !*name || !strcmp (name, "localhost"))
-    return;
+  if (name && *name && !http_parse_uri (&parsed_uri, name, 1))
+    {
+      if (parsed_uri->v6lit)
+        {
+          host_buffer = strconcat ("[", parsed_uri->host, "]", NULL);
+          if (!host_buffer)
+            log_error ("out of core in mark_host_dead");
+          host = host_buffer;
+        }
+      else
+        host = parsed_uri->host;
+    }
+  else
+    host = name;
 
-  idx = find_hostinfo (name);
-  if (idx == -1)
-    return;
-  hi = hosttable[idx];
-  log_info ("marking host '%s' as dead%s\n", hi->name, hi->dead? " (again)":"");
-  hi->dead = 1;
+  if (host && *host && strcmp (host, "localhost"))
+    {
+      hostinfo_t hi;
+      int idx;
+
+      idx = find_hostinfo (host);
+      if (idx != -1)
+        {
+          hi = hosttable[idx];
+          log_info ("marking host '%s' as dead%s\n",
+                    hi->name, hi->dead? " (again)":"");
+          hi->dead = 1;
+          done = 1;
+        }
+    }
+
+  http_release_parsed_uri (parsed_uri);
+  xfree (host_buffer);
+  return done;
 }
 
 
@@ -566,7 +599,8 @@ ks_hkp_help (ctrl_t ctrl, parsed_uri_t uri)
    PORT.  Returns an allocated string or NULL on failure and sets
    ERRNO.  */
 static char *
-make_host_part (const char *scheme, const char *host, unsigned short port,
+make_host_part (ctrl_t ctrl,
+                const char *scheme, const char *host, unsigned short port,
                 int force_reselect)
 {
   char portstr[10];
@@ -591,7 +625,7 @@ make_host_part (const char *scheme, const char *host, unsigned short port,
       /*fixme_do_srv_lookup ()*/
     }
 
-  hostname = map_host (host, force_reselect);
+  hostname = map_host (ctrl, host, force_reselect);
   if (!hostname)
     return NULL;
 
@@ -610,7 +644,7 @@ ks_hkp_resolve (ctrl_t ctrl, parsed_uri_t uri)
   gpg_error_t err;
   char *hostport = NULL;
 
-  hostport = make_host_part (uri->scheme, uri->host, uri->port, 1);
+  hostport = make_host_part (ctrl, uri->scheme, uri->host, uri->port, 1);
   if (!hostport)
     {
       err = gpg_error_from_syserror ();
@@ -746,6 +780,42 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr,
 }
 
 
+/* Helper to evaluate the error code ERR form a send_request() call
+   with REQUEST.  The function returns true if the caller shall try
+   again.  TRIES_LEFT points to a variable to track the number of
+   retries; this function decrements it and won't return true if it is
+   down to zero. */
+static int
+handle_send_request_error (gpg_error_t err, const char *request,
+                           unsigned int *tries_left)
+{
+  int retry = 0;
+
+  switch (gpg_err_code (err))
+    {
+    case GPG_ERR_ECONNREFUSED:
+    case GPG_ERR_ENETUNREACH:
+      if (mark_host_dead (request) && *tries_left)
+        retry = 1;
+      break;
+
+    case GPG_ERR_ETIMEDOUT:
+      if (*tries_left)
+        {
+          log_info ("selecting a different host due to a timeout\n");
+          retry = 1;
+        }
+
+    default:
+      break;
+    }
+
+  if (*tries_left)
+    --*tries_left;
+
+  return retry;
+}
+
 static gpg_error_t
 armor_data (char **r_string, const void *data, size_t datalen)
 {
@@ -817,6 +887,8 @@ ks_hkp_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern,
   char *hostport = NULL;
   char *request = NULL;
   estream_t fp = NULL;
+  int reselect;
+  unsigned int tries = SEND_REQUEST_RETRIES;
 
   *r_fp = NULL;
 
@@ -858,10 +930,14 @@ ks_hkp_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern,
     }
 
   /* Build the request string.  */
+  reselect = 0;
+ again:
   {
     char *searchkey;
 
-    hostport = make_host_part (uri->scheme, uri->host, uri->port, 0);
+    xfree (hostport);
+    hostport = make_host_part (ctrl, uri->scheme, uri->host, uri->port,
+                               reselect);
     if (!hostport)
       {
         err = gpg_error_from_syserror ();
@@ -875,6 +951,7 @@ ks_hkp_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern,
         goto leave;
       }
 
+    xfree (request);
     request = strconcat (hostport,
                          "/pks/lookup?op=index&options=mr&search=",
                          searchkey,
@@ -889,6 +966,11 @@ ks_hkp_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern,
 
   /* Send the request.  */
   err = send_request (ctrl, request, hostport, NULL, NULL, &fp);
+  if (handle_send_request_error (err, request, &tries))
+    {
+      reselect = 1;
+      goto again;
+    }
   if (err)
     goto leave;
 
@@ -935,6 +1017,8 @@ ks_hkp_get (ctrl_t ctrl, parsed_uri_t uri, const char *keyspec, estream_t *r_fp)
   char *hostport = NULL;
   char *request = NULL;
   estream_t fp = NULL;
+  int reselect;
+  unsigned int tries = SEND_REQUEST_RETRIES;
 
   *r_fp = NULL;
 
@@ -966,14 +1050,18 @@ ks_hkp_get (ctrl_t ctrl, parsed_uri_t uri, const char *keyspec, estream_t *r_fp)
       return gpg_error (GPG_ERR_INV_USER_ID);
     }
 
+  reselect = 0;
+ again:
   /* Build the request string.  */
-  hostport = make_host_part (uri->scheme, uri->host, uri->port, 0);
+  xfree (hostport);
+  hostport = make_host_part (ctrl, uri->scheme, uri->host, uri->port, reselect);
   if (!hostport)
     {
       err = gpg_error_from_syserror ();
       goto leave;
     }
 
+  xfree (request);
   request = strconcat (hostport,
                        "/pks/lookup?op=get&options=mr&search=0x",
                        kidbuf,
@@ -986,6 +1074,11 @@ ks_hkp_get (ctrl_t ctrl, parsed_uri_t uri, const char *keyspec, estream_t *r_fp)
 
   /* Send the request.  */
   err = send_request (ctrl, request, hostport, NULL, NULL, &fp);
+  if (handle_send_request_error (err, request, &tries))
+    {
+      reselect = 1;
+      goto again;
+    }
   if (err)
     goto leave;
 
@@ -1042,6 +1135,8 @@ ks_hkp_put (ctrl_t ctrl, parsed_uri_t uri, const void *data, size_t datalen)
   estream_t fp = NULL;
   struct put_post_parm_s parm;
   char *armored = NULL;
+  int reselect;
+  unsigned int tries = SEND_REQUEST_RETRIES;
 
   parm.datastring = NULL;
 
@@ -1059,13 +1154,17 @@ ks_hkp_put (ctrl_t ctrl, parsed_uri_t uri, const void *data, size_t datalen)
   armored = NULL;
 
   /* Build the request string.  */
-  hostport = make_host_part (uri->scheme, uri->host, uri->port, 0);
+  reselect = 0;
+ again:
+  xfree (hostport);
+  hostport = make_host_part (ctrl, uri->scheme, uri->host, uri->port, reselect);
   if (!hostport)
     {
       err = gpg_error_from_syserror ();
       goto leave;
     }
 
+  xfree (request);
   request = strconcat (hostport, "/pks/add", NULL);
   if (!request)
     {
@@ -1075,6 +1174,11 @@ ks_hkp_put (ctrl_t ctrl, parsed_uri_t uri, const void *data, size_t datalen)
 
   /* Send the request.  */
   err = send_request (ctrl, request, hostport, put_post_cb, &parm, &fp);
+  if (handle_send_request_error (err, request, &tries))
+    {
+      reselect = 1;
+      goto again;
+    }
   if (err)
     goto leave;
 

commit 99135b89ced35d867dddadf9d51e63a3d8837fc3
Author: Werner Koch <wk at gnupg.org>
Date:   Wed Mar 12 14:27:50 2014 +0100

    Comment typo fixes
    
    --

diff --git a/dirmngr/server.c b/dirmngr/server.c
index fb619df..a1d2033 100644
--- a/dirmngr/server.c
+++ b/dirmngr/server.c
@@ -2130,7 +2130,7 @@ dirmngr_status_help (ctrl_t ctrl, const char *text)
   return err;
 }
 
-/* Send a tick progress indicator back.  Fixme: This is only does for
+/* Send a tick progress indicator back.  Fixme: This is only done for
    the currently active channel.  */
 gpg_error_t
 dirmngr_tick (ctrl_t ctrl)
diff --git a/g10/call-dirmngr.c b/g10/call-dirmngr.c
index 75f25f8..2310d8b 100644
--- a/g10/call-dirmngr.c
+++ b/g10/call-dirmngr.c
@@ -71,10 +71,10 @@ struct ks_put_parm_s
 
 /* Data used to associate an session with dirmngr contexts.  We can't
    use a simple one to one mapping because we sometimes need two
-   connection s to the dirmngr; for example while doing a listing and
+   connections to the dirmngr; for example while doing a listing and
    being in a data callback we may want to retrieve a key.  The local
    dirmngr data takes care of this.  At the end of the session the
-   function dirmngr_deinit_session_data is called bu gpg.c to cleanup
+   function dirmngr_deinit_session_data is called by gpg.c to cleanup
    these resources.  Note that gpg.h defines a typedef dirmngr_local_t
    for this structure. */
 struct dirmngr_local_s
@@ -109,9 +109,8 @@ gpg_dirmngr_deinit_session_data (ctrl_t ctrl)
 }
 
 
-/* Try to connect to the Dirmngr via a socket or fork it off if
-   possible.  Handle the server's initial greeting and set global
-   options.  */
+/* Try to connect to the Dirmngr via a socket or spawn it if possible.
+   Handle the server's initial greeting and set global options.  */
 static gpg_error_t
 create_context (ctrl_t ctrl, assuan_context_t *r_ctx)
 {
@@ -135,7 +134,9 @@ create_context (ctrl_t ctrl, assuan_context_t *r_ctx)
 
       /* Set all configured keyservers.  We clear existing keyservers
          so that any keyserver configured in GPG overrides keyservers
-         possibly configured in Dirmngr. */
+         possibly still configured in Dirmngr for the session (Note
+         that the keyserver list of a session in Dirmngr survives a
+         RESET. */
       for (ksi = opt.keyserver; !err && ksi; ksi = ksi->next)
         {
           char *line;
@@ -166,8 +167,8 @@ create_context (ctrl_t ctrl, assuan_context_t *r_ctx)
 
 
 /* Get a context for accessing dirmngr.  If no context is available a
-   new one is created and - if requred - dirmngr started.  On success
-   an assuan context is stored at R_CTX.  This Context may only be
+   new one is created and - if required - dirmngr started.  On success
+   an assuan context is stored at R_CTX.  This context may only be
    released by means of close_context.  Note that NULL is stored at
    R_CTX on error.  */
 static gpg_error_t
@@ -199,7 +200,7 @@ open_context (ctrl_t ctrl, assuan_context_t *r_ctx)
           xfree (dml);
           return err;
         }
-      /* To be on the Pth thread safe site we need to add it to a
+      /* To be on the nPth thread safe site we need to add it to a
          list; this is far easier than to have a lock for this
          function.  It should not happen anyway but the code is free
          because we need it for the is_active check above.  */
diff --git a/g10/keyserver.c b/g10/keyserver.c
index 28b4a10..b8ab81e 100644
--- a/g10/keyserver.c
+++ b/g10/keyserver.c
@@ -1650,13 +1650,16 @@ keyserver_put (ctrl_t ctrl, strlist_t keyspecs,
 }
 
 
+/* Loop over all URLs in STRLIST and fetch the key that URL.  Note
+   that the fetch operation ignores the configured key servers and
+   instead directly retrieves the keys.  */
 int
 keyserver_fetch (ctrl_t ctrl, strlist_t urilist)
 {
   gpg_error_t err;
   strlist_t sl;
   estream_t datastream;
-  unsigned int options = opt.keyserver_options.import_options;
+  unsigned int save_options = opt.keyserver_options.import_options;
 
   /* Switch on fast-import, since fetch can handle more than one
      import and we don't want each set to rebuild the trustdb.
@@ -1686,7 +1689,7 @@ keyserver_fetch (ctrl_t ctrl, strlist_t urilist)
       es_fclose (datastream);
     }
 
-  opt.keyserver_options.import_options = options;
+  opt.keyserver_options.import_options = save_options;
 
   /* If the original options didn't have fast import, and the trustdb
      is dirty, rebuild. */

commit 3d9e0eb02ce2b2e153e25deb0fc4b27b45f5026a
Author: Werner Koch <wk at gnupg.org>
Date:   Wed Mar 12 14:26:41 2014 +0100

    http: Add a flag to the URL parser indicating a literal v6 address.
    
    * common/http.h (struct parsed_uri_t): Add field v6lit.
    * common/http.c (do_parse_uri): Set v6lit.

diff --git a/common/http.c b/common/http.c
index d2f13e4..d95a2fb 100644
--- a/common/http.c
+++ b/common/http.c
@@ -781,6 +781,7 @@ do_parse_uri (parsed_uri_t uri, int only_local_part, int no_scheme_check)
   uri->use_tls = 0;
   uri->is_http = 0;
   uri->opaque = 0;
+  uri->v6lit = 0;
 
   /* A quick validity check. */
   if (strspn (p, VALID_URI_CHARS) != n)
@@ -841,6 +842,7 @@ do_parse_uri (parsed_uri_t uri, int only_local_part, int no_scheme_check)
 	      *p3++ = '\0';
 	      /* worst case, uri->host should have length 0, points to \0 */
 	      uri->host = p + 1;
+              uri->v6lit = 1;
 	      p = p3;
 	    }
 	  else
diff --git a/common/http.h b/common/http.h
index 75d64d1..bea9f07 100644
--- a/common/http.h
+++ b/common/http.h
@@ -51,6 +51,7 @@ struct parsed_uri_s
   unsigned int is_http:1; /* This is a HTTP style URI.   */
   unsigned int use_tls:1; /* Whether TLS should be used. */
   unsigned int opaque:1;/* Unknown scheme; PATH has the rest.  */
+  unsigned int v6lit:1; /* Host was given as a literal v6 address.  */
   char *auth;           /* username/password for basic auth.  */
   char *host; 	        /* Host (converted to lowercase). */
   unsigned short port;  /* Port (always set if the host is set). */

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

Summary of changes:
 common/http.c           |    2 +
 common/http.h           |    1 +
 dirmngr/ks-action.c     |   35 +++++++-----
 dirmngr/ks-engine-hkp.c |  142 ++++++++++++++++++++++++++++++++++++++++-------
 dirmngr/server.c        |    2 +-
 g10/call-dirmngr.c      |   19 ++++---
 g10/keyserver.c         |    7 ++-
 7 files changed, 162 insertions(+), 46 deletions(-)


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




More information about the Gnupg-commits mailing list