1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-04-17 15:44:34 +02:00

dirmngr: Make use of IPv4 and IPV6 more explicit.

* common/http.c (connect_server): Handle the new flags.
* common/http.h (HTTP_FLAG_IGNORE_IPv4, HTTP_FLAG_IGNORE_IPv4): New.
* dirmngr/ks-engine-hkp.c (map_host): Add arg r_httpflags.
(make_host_part): Ditto.
(send_request): Add arg httpflags.
(ks_hkp_search, ks_hkp_get, ks_hkp_put): Handle httpflags.
This commit is contained in:
Werner Koch 2014-03-14 17:00:10 +01:00
parent d7fbefeb82
commit 59b4fb5f49
3 changed files with 47 additions and 18 deletions

View File

@ -1,6 +1,7 @@
/* http.c - HTTP protocol handler /* http.c - HTTP protocol handler
* Copyright (C) 1999, 2001, 2002, 2003, 2004, 2006, 2009, 2010, * Copyright (C) 1999, 2001, 2002, 2003, 2004, 2006, 2009, 2010,
* 2011 Free Software Foundation, Inc. * 2011 Free Software Foundation, Inc.
* Copyright (C) 2014 Werner Koch
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@ -1706,8 +1707,6 @@ connect_server (const char *server, unsigned short port,
#ifdef HAVE_W32_SYSTEM #ifdef HAVE_W32_SYSTEM
unsigned long inaddr; unsigned long inaddr;
#endif #endif
/* Not currently using the flags */
(void)flags;
*r_host_not_found = 0; *r_host_not_found = 0;
#ifdef HAVE_W32_SYSTEM #ifdef HAVE_W32_SYSTEM
@ -1790,6 +1789,11 @@ connect_server (const char *server, unsigned short port,
for (ai = res; ai && !connected; ai = ai->ai_next) for (ai = res; ai && !connected; ai = ai->ai_next)
{ {
if (ai->ai_family == AF_INET && (flags & HTTP_FLAG_IGNORE_IPv4))
continue;
if (ai->ai_family == AF_INET6 && (flags & HTTP_FLAG_IGNORE_IPv6))
continue;
if (sock != -1) if (sock != -1)
sock_close (sock); sock_close (sock);
sock = socket (ai->ai_family, ai->ai_socktype, ai->ai_protocol); sock = socket (ai->ai_family, ai->ai_socktype, ai->ai_protocol);

View File

@ -74,10 +74,12 @@ http_req_t;
/* We put the flag values into an enum, so that gdb can display them. */ /* We put the flag values into an enum, so that gdb can display them. */
enum enum
{ {
HTTP_FLAG_TRY_PROXY = 1, HTTP_FLAG_TRY_PROXY = 1, /* Try to use a proxy. */
HTTP_FLAG_SHUTDOWN = 2, HTTP_FLAG_SHUTDOWN = 2, /* Close sending end after the request. */
HTTP_FLAG_LOG_RESP = 8, HTTP_FLAG_LOG_RESP = 8, /* Log the server respone. */
HTTP_FLAG_IGNORE_CL = 32 HTTP_FLAG_IGNORE_CL = 32, /* Ignore content-length. */
HTTP_FLAG_IGNORE_IPv4 = 64, /* Do not use IPv4. */
HTTP_FLAG_IGNORE_IPv6 = 128 /* Do not use IPv6. */
}; };
struct http_context_s; struct http_context_s;

View File

@ -249,13 +249,18 @@ my_getnameinfo (struct addrinfo *ai, char *host, size_t hostlen)
to choose one of the hosts. For example we skip those hosts which to choose one of the hosts. For example we skip those hosts which
failed for some time and we stick to one host for a time failed for some time and we stick to one host for a time
independent of DNS retry times. If FORCE_RESELECT is true a new independent of DNS retry times. If FORCE_RESELECT is true a new
host is always selected. */ host is always selected. If R_HTTPFLAGS is not NULL if will
received flags which are to be passed to http_open. */
static char * static char *
map_host (ctrl_t ctrl, const char *name, int force_reselect) map_host (ctrl_t ctrl, const char *name, int force_reselect,
unsigned int *r_httpflags)
{ {
hostinfo_t hi; hostinfo_t hi;
int idx; int idx;
if (r_httpflags)
*r_httpflags = 0;
/* No hostname means localhost. */ /* No hostname means localhost. */
if (!name || !*name) if (!name || !*name)
return xtrystrdup ("localhost"); return xtrystrdup ("localhost");
@ -406,6 +411,18 @@ map_host (ctrl_t ctrl, const char *name, int force_reselect)
return NULL; return NULL;
} }
if (r_httpflags)
{
/* If the hosttable does not indicate that a certain host
supports IPv<N>, we explicit set the corresponding http
flags. The reason for this is that a host might be listed in
a pool as not v6 only but actually support v6 when later
resolved the name is resolved by our http layer. */
if (!hi->v4)
*r_httpflags |= HTTP_FLAG_IGNORE_IPv4;
if (!hi->v6)
*r_httpflags |= HTTP_FLAG_IGNORE_IPv6;
}
return xtrystrdup (hi->name); return xtrystrdup (hi->name);
} }
@ -605,7 +622,7 @@ ks_hkp_help (ctrl_t ctrl, parsed_uri_t uri)
static char * static char *
make_host_part (ctrl_t ctrl, make_host_part (ctrl_t ctrl,
const char *scheme, const char *host, unsigned short port, const char *scheme, const char *host, unsigned short port,
int force_reselect) int force_reselect, unsigned int *r_httpflags)
{ {
char portstr[10]; char portstr[10];
char *hostname; char *hostname;
@ -629,7 +646,7 @@ make_host_part (ctrl_t ctrl,
/*fixme_do_srv_lookup ()*/ /*fixme_do_srv_lookup ()*/
} }
hostname = map_host (ctrl, host, force_reselect); hostname = map_host (ctrl, host, force_reselect, r_httpflags);
if (!hostname) if (!hostname)
return NULL; return NULL;
@ -648,7 +665,7 @@ ks_hkp_resolve (ctrl_t ctrl, parsed_uri_t uri)
gpg_error_t err; gpg_error_t err;
char *hostport = NULL; char *hostport = NULL;
hostport = make_host_part (ctrl, uri->scheme, uri->host, uri->port, 1); hostport = make_host_part (ctrl, uri->scheme, uri->host, uri->port, 1, NULL);
if (!hostport) if (!hostport)
{ {
err = gpg_error_from_syserror (); err = gpg_error_from_syserror ();
@ -671,6 +688,7 @@ ks_hkp_resolve (ctrl_t ctrl, parsed_uri_t uri)
writing the post data. */ writing the post data. */
static gpg_error_t static gpg_error_t
send_request (ctrl_t ctrl, const char *request, const char *hostportstr, send_request (ctrl_t ctrl, const char *request, const char *hostportstr,
unsigned int httpflags,
gpg_error_t (*post_cb)(void *, http_t), void *post_cb_value, gpg_error_t (*post_cb)(void *, http_t), void *post_cb_value,
estream_t *r_fp) estream_t *r_fp)
{ {
@ -687,7 +705,7 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr,
post_cb? HTTP_REQ_POST : HTTP_REQ_GET, post_cb? HTTP_REQ_POST : HTTP_REQ_GET,
request, request,
/* fixme: AUTH */ NULL, /* fixme: AUTH */ NULL,
0, httpflags,
/* fixme: proxy*/ NULL, /* fixme: proxy*/ NULL,
NULL, NULL, NULL, NULL,
/*FIXME curl->srvtag*/NULL); /*FIXME curl->srvtag*/NULL);
@ -892,6 +910,7 @@ ks_hkp_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern,
char *request = NULL; char *request = NULL;
estream_t fp = NULL; estream_t fp = NULL;
int reselect; int reselect;
unsigned int httpflags;
unsigned int tries = SEND_REQUEST_RETRIES; unsigned int tries = SEND_REQUEST_RETRIES;
*r_fp = NULL; *r_fp = NULL;
@ -941,7 +960,7 @@ ks_hkp_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern,
xfree (hostport); xfree (hostport);
hostport = make_host_part (ctrl, uri->scheme, uri->host, uri->port, hostport = make_host_part (ctrl, uri->scheme, uri->host, uri->port,
reselect); reselect, &httpflags);
if (!hostport) if (!hostport)
{ {
err = gpg_error_from_syserror (); err = gpg_error_from_syserror ();
@ -969,7 +988,7 @@ ks_hkp_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern,
} }
/* Send the request. */ /* Send the request. */
err = send_request (ctrl, request, hostport, NULL, NULL, &fp); err = send_request (ctrl, request, hostport, httpflags, NULL, NULL, &fp);
if (handle_send_request_error (err, request, &tries)) if (handle_send_request_error (err, request, &tries))
{ {
reselect = 1; reselect = 1;
@ -1026,6 +1045,7 @@ ks_hkp_get (ctrl_t ctrl, parsed_uri_t uri, const char *keyspec, estream_t *r_fp)
char *request = NULL; char *request = NULL;
estream_t fp = NULL; estream_t fp = NULL;
int reselect; int reselect;
unsigned int httpflags;
unsigned int tries = SEND_REQUEST_RETRIES; unsigned int tries = SEND_REQUEST_RETRIES;
*r_fp = NULL; *r_fp = NULL;
@ -1062,7 +1082,8 @@ ks_hkp_get (ctrl_t ctrl, parsed_uri_t uri, const char *keyspec, estream_t *r_fp)
again: again:
/* Build the request string. */ /* Build the request string. */
xfree (hostport); xfree (hostport);
hostport = make_host_part (ctrl, uri->scheme, uri->host, uri->port, reselect); hostport = make_host_part (ctrl, uri->scheme, uri->host, uri->port,
reselect, &httpflags);
if (!hostport) if (!hostport)
{ {
err = gpg_error_from_syserror (); err = gpg_error_from_syserror ();
@ -1081,7 +1102,7 @@ ks_hkp_get (ctrl_t ctrl, parsed_uri_t uri, const char *keyspec, estream_t *r_fp)
} }
/* Send the request. */ /* Send the request. */
err = send_request (ctrl, request, hostport, NULL, NULL, &fp); err = send_request (ctrl, request, hostport, httpflags, NULL, NULL, &fp);
if (handle_send_request_error (err, request, &tries)) if (handle_send_request_error (err, request, &tries))
{ {
reselect = 1; reselect = 1;
@ -1148,6 +1169,7 @@ ks_hkp_put (ctrl_t ctrl, parsed_uri_t uri, const void *data, size_t datalen)
struct put_post_parm_s parm; struct put_post_parm_s parm;
char *armored = NULL; char *armored = NULL;
int reselect; int reselect;
unsigned int httpflags;
unsigned int tries = SEND_REQUEST_RETRIES; unsigned int tries = SEND_REQUEST_RETRIES;
parm.datastring = NULL; parm.datastring = NULL;
@ -1169,7 +1191,8 @@ ks_hkp_put (ctrl_t ctrl, parsed_uri_t uri, const void *data, size_t datalen)
reselect = 0; reselect = 0;
again: again:
xfree (hostport); xfree (hostport);
hostport = make_host_part (ctrl, uri->scheme, uri->host, uri->port, reselect); hostport = make_host_part (ctrl, uri->scheme, uri->host, uri->port,
reselect, &httpflags);
if (!hostport) if (!hostport)
{ {
err = gpg_error_from_syserror (); err = gpg_error_from_syserror ();
@ -1185,7 +1208,7 @@ ks_hkp_put (ctrl_t ctrl, parsed_uri_t uri, const void *data, size_t datalen)
} }
/* Send the request. */ /* Send the request. */
err = send_request (ctrl, request, hostport, put_post_cb, &parm, &fp); err = send_request (ctrl, request, hostport, 0, put_post_cb, &parm, &fp);
if (handle_send_request_error (err, request, &tries)) if (handle_send_request_error (err, request, &tries))
{ {
reselect = 1; reselect = 1;