diff options
Diffstat (limited to 'dirmngr/ks-engine-hkp.c')
-rw-r--r-- | dirmngr/ks-engine-hkp.c | 110 |
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)); +} |