aboutsummaryrefslogtreecommitdiffstats
path: root/dirmngr/ks-engine-hkp.c
diff options
context:
space:
mode:
Diffstat (limited to 'dirmngr/ks-engine-hkp.c')
-rw-r--r--dirmngr/ks-engine-hkp.c110
1 files changed, 85 insertions, 25 deletions
diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c
index 32840e68e..790a8b1c5 100644
--- a/dirmngr/ks-engine-hkp.c
+++ b/dirmngr/ks-engine-hkp.c
@@ -35,6 +35,7 @@
# include <netdb.h>
#endif /*!HAVE_W32_SYSTEM*/
+#include <npth.h>
#include "dirmngr.h"
#include "misc.h"
#include "../common/userids.h"
@@ -108,6 +109,8 @@ struct hostinfo_s
resolved from a pool name and its allocated size.*/
static hostinfo_t *hosttable;
static int hosttable_size;
+/* A mutex used to serialize access to the hosttable. */
+static npth_mutex_t hosttable_lock;
/* The number of host slots we initially allocate for HOSTTABLE. */
#define INITIAL_HOSTTABLE_SIZE 50
@@ -304,7 +307,7 @@ tor_not_running_p (ctrl_t ctrl)
PROTOCOL. If NAME specifies a pool (as indicated by IS_POOL),
update the given reference table accordingly. */
static void
-add_host (const char *name, int is_pool,
+add_host (ctrl_t ctrl, const char *name, int is_pool,
const dns_addrinfo_t ai,
enum ks_protocol protocol, unsigned short port)
{
@@ -320,7 +323,7 @@ add_host (const char *name, int is_pool,
if (is_pool)
{
/* For a pool immediately convert the address to a string. */
- tmperr = resolve_dns_addr (ai->addr, ai->addrlen,
+ tmperr = resolve_dns_addr (ctrl, ai->addr, ai->addrlen,
(DNS_NUMERICHOST | DNS_WITHBRACKET), &tmphost);
}
else if (!is_ip_address (name))
@@ -337,7 +340,7 @@ add_host (const char *name, int is_pool,
{
/* Do a PTR lookup on AI. If a name was not found the function
* returns the numeric address (with brackets). */
- tmperr = resolve_dns_addr (ai->addr, ai->addrlen,
+ tmperr = resolve_dns_addr (ctrl, ai->addr, ai->addrlen,
DNS_WITHBRACKET, &tmphost);
}
@@ -498,7 +501,7 @@ map_host (ctrl_t ctrl, const char *name, const char *srvtag, int force_reselect,
unsigned int srvscount;
/* Check for SRV records. */
- err = get_dns_srv (name, srvtag, NULL, &srvs, &srvscount);
+ err = get_dns_srv (ctrl, name, srvtag, NULL, &srvs, &srvscount);
if (err)
{
if (gpg_err_code (err) == GPG_ERR_ECONNREFUSED)
@@ -514,13 +517,13 @@ map_host (ctrl_t ctrl, const char *name, const char *srvtag, int force_reselect,
for (i = 0; i < srvscount; i++)
{
- err = resolve_dns_name (srvs[i].target, 0,
+ err = resolve_dns_name (ctrl, srvs[i].target, 0,
AF_UNSPEC, SOCK_STREAM,
&ai, &cname);
if (err)
continue;
dirmngr_tick (ctrl);
- add_host (name, is_pool, ai, protocol, srvs[i].port);
+ add_host (ctrl, name, is_pool, ai, protocol, srvs[i].port);
new_hosts = 1;
}
@@ -535,7 +538,7 @@ map_host (ctrl_t ctrl, const char *name, const char *srvtag, int force_reselect,
{
/* Find all A records for this entry and put them into the pool
list - if any. */
- err = resolve_dns_name (name, 0, 0, SOCK_STREAM, &aibuf, &cname);
+ err = resolve_dns_name (ctrl, name, 0, 0, SOCK_STREAM, &aibuf, &cname);
if (err)
{
log_error ("resolving '%s' failed: %s\n", name, gpg_strerror (err));
@@ -566,7 +569,7 @@ map_host (ctrl_t ctrl, const char *name, const char *srvtag, int force_reselect,
continue;
dirmngr_tick (ctrl);
- add_host (name, is_pool, ai, 0, 0);
+ add_host (ctrl, name, is_pool, ai, 0, 0);
new_hosts = 1;
}
@@ -624,7 +627,7 @@ map_host (ctrl_t ctrl, const char *name, const char *srvtag, int force_reselect,
* hosttable. */
char *host;
- err = resolve_dns_name (hi->name, 0, 0, SOCK_STREAM, &aibuf, NULL);
+ err = resolve_dns_name (ctrl, hi->name, 0, 0, SOCK_STREAM, &aibuf, NULL);
if (!err)
{
for (ai = aibuf; ai; ai = ai->next)
@@ -632,7 +635,8 @@ map_host (ctrl_t ctrl, const char *name, const char *srvtag, int force_reselect,
if ((!opt.disable_ipv6 && ai->family == AF_INET6)
|| (!opt.disable_ipv4 && ai->family == AF_INET))
{
- err = resolve_dns_addr (ai->addr, ai->addrlen, 0, &host);
+ err = resolve_dns_addr (ctrl,
+ ai->addr, ai->addrlen, 0, &host);
if (!err)
{
/* Okay, we return the first found name. */
@@ -755,9 +759,15 @@ ks_hkp_mark_host (ctrl_t ctrl, const char *name, int alive)
if (!name || !*name || !strcmp (name, "localhost"))
return 0;
+ if (npth_mutex_lock (&hosttable_lock))
+ log_fatal ("failed to acquire mutex\n");
+
idx = find_hostinfo (name);
if (idx == -1)
- return gpg_error (GPG_ERR_NOT_FOUND);
+ {
+ err = gpg_error (GPG_ERR_NOT_FOUND);
+ goto leave;
+ }
hi = hosttable[idx];
if (alive && hi->dead)
@@ -816,6 +826,10 @@ ks_hkp_mark_host (ctrl_t ctrl, const char *name, int alive)
}
}
+ leave:
+ if (npth_mutex_unlock (&hosttable_lock))
+ log_fatal ("failed to release mutex\n");
+
return err;
}
@@ -836,7 +850,9 @@ ks_hkp_print_hosttable (ctrl_t ctrl)
if (err)
return err;
- /* FIXME: We need a lock for the hosttable. */
+ if (npth_mutex_lock (&hosttable_lock))
+ log_fatal ("failed to acquire mutex\n");
+
curtime = gnupg_get_time ();
for (idx=0; idx < hosttable_size; idx++)
if ((hi=hosttable[idx]))
@@ -865,7 +881,7 @@ ks_hkp_print_hosttable (ctrl_t ctrl)
/* Turn the numerical IP address string into an AI and
* then do a DNS PTR lookup. */
- if (!resolve_dns_name (hi->name, 0, 0,
+ if (!resolve_dns_name (ctrl, hi->name, 0, 0,
SOCK_STREAM,
&aibuf, &canon))
{
@@ -876,7 +892,7 @@ ks_hkp_print_hosttable (ctrl_t ctrl)
}
for (ai = aibuf; !canon && ai; ai = ai->next)
{
- resolve_dns_addr (ai->addr, ai->addrlen,
+ resolve_dns_addr (ctrl, ai->addr, ai->addrlen,
DNS_WITHBRACKET, &canon);
if (canon && is_ip_address (canon))
{
@@ -896,14 +912,14 @@ ks_hkp_print_hosttable (ctrl_t ctrl)
/* Get the IP address as a string from a name. Note
* that resolve_dns_addr allocates CANON on success
* and thus terminates the loop. */
- if (!resolve_dns_name (hi->name, 0,
+ if (!resolve_dns_name (ctrl, hi->name, 0,
hi->v6? AF_INET6 : AF_INET,
SOCK_STREAM,
&aibuf, NULL))
{
for (ai = aibuf; !canon && ai; ai = ai->next)
{
- resolve_dns_addr (ai->addr, ai->addrlen,
+ resolve_dns_addr (ctrl, ai->addr, ai->addrlen,
DNS_NUMERICHOST|DNS_WITHBRACKET,
&canon);
}
@@ -929,12 +945,12 @@ ks_hkp_print_hosttable (ctrl_t ctrl)
diedstr? ")":"" );
xfree (died);
if (err)
- return err;
+ goto leave;
if (hi->cname)
err = ks_printf_help (ctrl, " . %s", hi->cname);
if (err)
- return err;
+ goto leave;
if (hi->pool)
{
@@ -949,14 +965,21 @@ ks_hkp_print_hosttable (ctrl_t ctrl)
put_membuf( &mb, "", 1);
p = get_membuf (&mb, NULL);
if (!p)
- return gpg_error_from_syserror ();
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
err = ks_print_help (ctrl, p);
xfree (p);
if (err)
- return err;
+ goto leave;
}
}
- return 0;
+
+ leave:
+ if (npth_mutex_unlock (&hosttable_lock))
+ log_fatal ("failed to release mutex\n");
+ return err;
}
@@ -1025,9 +1048,16 @@ make_host_part (ctrl_t ctrl,
protocol = KS_PROTOCOL_HKP;
}
+ if (npth_mutex_lock (&hosttable_lock))
+ log_fatal ("failed to acquire mutex\n");
+
portstr[0] = 0;
err = map_host (ctrl, host, srvtag, force_reselect, protocol,
&hostname, portstr, r_httpflags, r_httphost);
+
+ if (npth_mutex_unlock (&hosttable_lock))
+ log_fatal ("failed to release mutex\n");
+
if (err)
return err;
@@ -1101,6 +1131,9 @@ ks_hkp_housekeeping (time_t curtime)
int idx;
hostinfo_t hi;
+ if (npth_mutex_lock (&hosttable_lock))
+ log_fatal ("failed to acquire mutex\n");
+
for (idx=0; idx < hosttable_size; idx++)
{
hi = hosttable[idx];
@@ -1117,6 +1150,9 @@ ks_hkp_housekeeping (time_t curtime)
log_info ("resurrected host '%s'", hi->name);
}
}
+
+ if (npth_mutex_unlock (&hosttable_lock))
+ log_fatal ("failed to release mutex\n");
}
@@ -1128,6 +1164,9 @@ ks_hkp_reload (void)
int idx, count;
hostinfo_t hi;
+ if (npth_mutex_lock (&hosttable_lock))
+ log_fatal ("failed to acquire mutex\n");
+
for (idx=count=0; idx < hosttable_size; idx++)
{
hi = hosttable[idx];
@@ -1141,6 +1180,9 @@ ks_hkp_reload (void)
}
if (count)
log_info ("number of resurrected hosts: %d", count);
+
+ if (npth_mutex_unlock (&hosttable_lock))
+ log_fatal ("failed to release mutex\n");
}
@@ -1182,7 +1224,7 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr,
http_session_set_timeout (session, ctrl->timeout);
once_more:
- err = http_open (&http,
+ err = http_open (ctrl, &http,
post_cb? HTTP_REQ_POST : HTTP_REQ_GET,
request,
httphost,
@@ -1339,7 +1381,7 @@ handle_send_request_error (ctrl_t ctrl, gpg_error_t err, const char *request,
int retry = 0;
/* Fixme: Should we disable all hosts of a protocol family if a
- * request for an address of that familiy returned ENETDOWN? */
+ * request for an address of that family returned ENETDOWN? */
switch (gpg_err_code (err))
{
@@ -1493,7 +1535,11 @@ ks_hkp_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern,
goto again;
}
if (err)
- goto leave;
+ {
+ if (gpg_err_code (err) == GPG_ERR_NO_DATA)
+ dirmngr_status (ctrl, "SOURCE", hostport, NULL);
+ goto leave;
+ }
err = dirmngr_status (ctrl, "SOURCE", hostport, NULL);
if (err)
@@ -1628,7 +1674,11 @@ ks_hkp_get (ctrl_t ctrl, parsed_uri_t uri, const char *keyspec, estream_t *r_fp)
goto again;
}
if (err)
- goto leave;
+ {
+ if (gpg_err_code (err) == GPG_ERR_NO_DATA)
+ dirmngr_status (ctrl, "SOURCE", hostport, NULL);
+ goto leave;
+ }
err = dirmngr_status (ctrl, "SOURCE", hostport, NULL);
if (err)
@@ -1748,3 +1798,13 @@ ks_hkp_put (ctrl_t ctrl, parsed_uri_t uri, const void *data, size_t datalen)
xfree (httphost);
return err;
}
+
+void
+ks_hkp_init (void)
+{
+ int err;
+
+ err = npth_mutex_init (&hosttable_lock, NULL);
+ if (err)
+ log_fatal ("error initializing mutex: %s\n", strerror (err));
+}