dirmngr: Avoid endless loop in case of HTTP error 503.

* dirmngr/ks-engine-hkp.c (SEND_REQUEST_EXTRA_RETRIES): New.
(handle_send_request_error): Use it for 503 and 504.
(ks_hkp_search, ks_hkp_get, ks_hkp_put): Pass a new var for
extra_tries.
--

This is a pretty stupid fix but one which works without much risk of
regressions.  We could have used the existing TRIES but in that case
the fallback to other host would have been too limited.  With the used
value we can have several fallbacks to other hosts.  Note that the
TRIES is still cumulative and not per host.

GnuPG-bug-id: 4600
Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2019-07-03 17:39:53 +02:00
parent 37f0c55c7b
commit 8b113bb148
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
1 changed files with 33 additions and 10 deletions

View File

@ -68,6 +68,10 @@
/* Number of retries done for a dead host etc. */
#define SEND_REQUEST_RETRIES 3
/* Number of retries done in case of transient errors. */
#define SEND_REQUEST_EXTRA_RETRIES 5
enum ks_protocol { KS_PROTOCOL_HKP, KS_PROTOCOL_HKPS, KS_PROTOCOL_MAX };
/* Objects used to maintain information about hosts. */
@ -1353,10 +1357,12 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr,
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. */
down to zero. EXTRA_TRIES_LEFT does the same but only for
transient http status codes. */
static int
handle_send_request_error (ctrl_t ctrl, gpg_error_t err, const char *request,
unsigned int http_status, unsigned int *tries_left)
unsigned int http_status, unsigned int *tries_left,
unsigned int *extra_tries_left)
{
int retry = 0;
@ -1412,9 +1418,12 @@ handle_send_request_error (ctrl_t ctrl, gpg_error_t err, const char *request,
case 503: /* Service Unavailable */
case 504: /* Gateway Timeout */
log_info ("selecting a different host due to a %u (%s)",
http_status, http_status2string (http_status));
retry = 1;
if (*extra_tries_left)
{
log_info ("selecting a different host due to a %u (%s)",
http_status, http_status2string (http_status));
retry = 2;
}
break;
}
}
@ -1424,8 +1433,16 @@ handle_send_request_error (ctrl_t ctrl, gpg_error_t err, const char *request,
break;
}
if (*tries_left)
--*tries_left;
if (retry == 2)
{
if (*extra_tries_left)
--*extra_tries_left;
}
else
{
if (*tries_left)
--*tries_left;
}
return retry;
}
@ -1450,6 +1467,7 @@ ks_hkp_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern,
char *httphost = NULL;
unsigned int http_status;
unsigned int tries = SEND_REQUEST_RETRIES;
unsigned int extra_tries = SEND_REQUEST_EXTRA_RETRIES;
*r_fp = NULL;
@ -1525,7 +1543,8 @@ ks_hkp_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern,
/* Send the request. */
err = send_request (ctrl, request, hostport, httphost, httpflags,
NULL, NULL, &fp, &http_status);
if (handle_send_request_error (ctrl, err, request, http_status, &tries))
if (handle_send_request_error (ctrl, err, request, http_status,
&tries, &extra_tries))
{
reselect = 1;
goto again;
@ -1595,6 +1614,7 @@ ks_hkp_get (ctrl_t ctrl, parsed_uri_t uri, const char *keyspec, estream_t *r_fp)
unsigned int httpflags;
unsigned int http_status;
unsigned int tries = SEND_REQUEST_RETRIES;
unsigned int extra_tries = SEND_REQUEST_EXTRA_RETRIES;
*r_fp = NULL;
@ -1668,7 +1688,8 @@ 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, httphost, httpflags,
NULL, NULL, &fp, &http_status);
if (handle_send_request_error (ctrl, err, request, http_status, &tries))
if (handle_send_request_error (ctrl, err, request, http_status,
&tries, &extra_tries))
{
reselect = 1;
goto again;
@ -1744,6 +1765,7 @@ ks_hkp_put (ctrl_t ctrl, parsed_uri_t uri, const void *data, size_t datalen)
unsigned int httpflags;
unsigned int http_status;
unsigned int tries = SEND_REQUEST_RETRIES;
unsigned int extra_tries = SEND_REQUEST_EXTRA_RETRIES;
parm.datastring = NULL;
@ -1782,7 +1804,8 @@ 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, httphost, 0,
put_post_cb, &parm, &fp, &http_status);
if (handle_send_request_error (ctrl, err, request, http_status, &tries))
if (handle_send_request_error (ctrl, err, request, http_status,
&tries, &extra_tries))
{
reselect = 1;
goto again;