summaryrefslogtreecommitdiffstats
path: root/dirmngr/domaininfo.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2017-11-14 08:37:27 +0100
committerWerner Koch <wk@gnupg.org>2017-11-14 09:04:52 +0100
commit26f08343fbccdbaa177c3507a3c5e24a5cf94a2d (patch)
tree8f237d69d93f29f075eedf4bfdc839b66ef16e97 /dirmngr/domaininfo.c
parentdirmngr: Keep track of domains used for WKD queries (diff)
downloadgnupg2-26f08343fbccdbaa177c3507a3c5e24a5cf94a2d.tar.xz
gnupg2-26f08343fbccdbaa177c3507a3c5e24a5cf94a2d.zip
dirmngr: Limit the number of cached domains for WKD.
* dirmngr/domaininfo.c (MAX_DOMAINBUCKET_LEN): New. (insert_or_update): Limit the length of a bucket chain. (domaininfo_print_stats): Print just one summary line. Signed-off-by: Werner Koch <wk@gnupg.org>
Diffstat (limited to 'dirmngr/domaininfo.c')
-rw-r--r--dirmngr/domaininfo.c62
1 files changed, 54 insertions, 8 deletions
diff --git a/dirmngr/domaininfo.c b/dirmngr/domaininfo.c
index 393db8c78..90cdb856c 100644
--- a/dirmngr/domaininfo.c
+++ b/dirmngr/domaininfo.c
@@ -26,7 +26,18 @@
#include "dirmngr.h"
-#define NO_OF_DOMAINBUCKETS 103
+/* Number of bucket for the hash array and limit for the length of a
+ * bucket chain. For debugging values of 13 and 10 are more suitable
+ * and a command like
+ * for j in a b c d e f g h i j k l m n o p q r s t u v w z y z; do \
+ * for i in a b c d e f g h i j k l m n o p q r s t u v w z y z; do \
+ * gpg-connect-agent --dirmngr "wkd_get foo@$i.$j.gnupg.net" /bye \
+ * >/dev/null ; done; done
+ * will quickly add a couple of domains.
+ */
+#define NO_OF_DOMAINBUCKETS 103
+#define MAX_DOMAINBUCKET_LEN 20
+
/* Object to keep track of a domain name. */
struct domaininfo_s
@@ -74,13 +85,18 @@ domaininfo_print_stats (void)
int bidx;
domaininfo_t di;
int count, no_name, wkd_not_found, wkd_supported, wkd_not_supported;
+ int len, minlen, maxlen;
+ count = no_name = wkd_not_found = wkd_supported = wkd_not_supported = 0;
+ maxlen = 0;
+ minlen = -1;
for (bidx = 0; bidx < NO_OF_DOMAINBUCKETS; bidx++)
{
- count = no_name = wkd_not_found = wkd_supported = wkd_not_supported = 0;
+ len = 0;
for (di = domainbuckets[bidx]; di; di = di->next)
{
count++;
+ len++;
if (di->no_name)
no_name++;
if (di->wkd_not_found)
@@ -90,11 +106,16 @@ domaininfo_print_stats (void)
if (di->wkd_not_supported)
wkd_not_supported++;
}
- if (count)
- log_info ("domaininfo: chain %3d length=%d nn=%d nf=%d s=%d ns=%d\n",
- bidx, count, no_name,
- wkd_not_found, wkd_supported, wkd_not_supported);
+ if (len > maxlen)
+ maxlen = len;
+ if (minlen == -1 || len < minlen)
+ minlen = len;
}
+ log_info ("domaininfo: items=%d chainlen=%d..%d nn=%d nf=%d ns=%d s=%d\n",
+ count,
+ minlen > 0? minlen : 0,
+ maxlen,
+ no_name, wkd_not_found, wkd_not_supported, wkd_supported);
}
@@ -122,7 +143,9 @@ insert_or_update (const char *domain,
{
domaininfo_t di;
domaininfo_t di_new;
+ domaininfo_t di_cut;
u32 hash;
+ int count;
hash = hash_domain (domain);
for (di = domainbuckets[hash]; di; di = di->next)
@@ -138,7 +161,8 @@ insert_or_update (const char *domain,
/* Need to do another lookup because the malloc is a system call and
* thus the hash array may have been changed by another thread. */
- for (di = domainbuckets[hash]; di; di = di->next)
+ di_cut = NULL;
+ for (count=0, di = domainbuckets[hash]; di; di = di->next, count++)
if (!strcmp (di->name, domain))
{
callback (di, 0); /* Update */
@@ -146,10 +170,32 @@ insert_or_update (const char *domain,
return;
}
- callback (di_new, 1); /* Insert */
+ /* Before we insert we need to check whether the chain gets too long. */
+ di_cut = NULL;
+ if (count >= MAX_DOMAINBUCKET_LEN)
+ {
+ for (count=0, di = domainbuckets[hash]; di; di = di->next, count++)
+ if (count >= MAX_DOMAINBUCKET_LEN/2)
+ {
+ di_cut = di->next;
+ di->next = NULL;
+ break;
+ }
+ }
+
+ /* Insert */
+ callback (di_new, 1);
di = di_new;
di->next = domainbuckets[hash];
domainbuckets[hash] = di;
+
+ /* Remove the rest of the cutted chain. */
+ while (di_cut)
+ {
+ di = di_cut->next;
+ xfree (di_cut);
+ di_cut = di;
+ }
}