1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-22 10:19:57 +01:00

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>
(cherry picked from commit 26f08343fbccdbaa177c3507a3c5e24a5cf94a2d)
This commit is contained in:
Werner Koch 2017-11-14 08:37:27 +01:00
parent 6c1dcd79cf
commit 7a663c296e
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B

View File

@ -26,7 +26,18 @@
#include "dirmngr.h" #include "dirmngr.h"
/* 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 NO_OF_DOMAINBUCKETS 103
#define MAX_DOMAINBUCKET_LEN 20
/* Object to keep track of a domain name. */ /* Object to keep track of a domain name. */
struct domaininfo_s struct domaininfo_s
@ -74,13 +85,18 @@ domaininfo_print_stats (void)
int bidx; int bidx;
domaininfo_t di; domaininfo_t di;
int count, no_name, wkd_not_found, wkd_supported, wkd_not_supported; 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++) 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) for (di = domainbuckets[bidx]; di; di = di->next)
{ {
count++; count++;
len++;
if (di->no_name) if (di->no_name)
no_name++; no_name++;
if (di->wkd_not_found) if (di->wkd_not_found)
@ -90,11 +106,16 @@ domaininfo_print_stats (void)
if (di->wkd_not_supported) if (di->wkd_not_supported)
wkd_not_supported++; wkd_not_supported++;
} }
if (count) if (len > maxlen)
log_info ("domaininfo: chain %3d length=%d nn=%d nf=%d s=%d ns=%d\n", maxlen = len;
bidx, count, no_name, if (minlen == -1 || len < minlen)
wkd_not_found, wkd_supported, wkd_not_supported); 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;
domaininfo_t di_new; domaininfo_t di_new;
domaininfo_t di_cut;
u32 hash; u32 hash;
int count;
hash = hash_domain (domain); hash = hash_domain (domain);
for (di = domainbuckets[hash]; di; di = di->next) 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 /* Need to do another lookup because the malloc is a system call and
* thus the hash array may have been changed by another thread. */ * 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)) if (!strcmp (di->name, domain))
{ {
callback (di, 0); /* Update */ callback (di, 0); /* Update */
@ -146,10 +170,32 @@ insert_or_update (const char *domain,
return; 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 = di_new;
di->next = domainbuckets[hash]; di->next = domainbuckets[hash];
domainbuckets[hash] = di; domainbuckets[hash] = di;
/* Remove the rest of the cutted chain. */
while (di_cut)
{
di = di_cut->next;
xfree (di_cut);
di_cut = di;
}
} }