mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
g10: Make the keyblock cache per-handle rather than global.
* g10/keydb.c (keyblock_cache): Don't declare this variable. Instead... (struct keyblock_cache): ... turn its type into this first class object... (struct keydb_handle): ... and instantiate it once per database handle. Update all users. (keydb_rebuild_caches): Don't invalidate the keyblock cache. -- Signed-off-by: Neal H. Walfield <neal@g10code.com>.
This commit is contained in:
parent
f076fa190e
commit
60bc518645
111
g10/keydb.c
111
g10/keydb.c
@ -62,6 +62,28 @@ static struct resource_item all_resources[MAX_KEYDB_RESOURCES];
|
|||||||
static int used_resources;
|
static int used_resources;
|
||||||
static void *primary_keyring=NULL;
|
static void *primary_keyring=NULL;
|
||||||
|
|
||||||
|
|
||||||
|
/* This is a simple cache used to return the last result of a
|
||||||
|
successful fingerprint search. This works only for keybox resources
|
||||||
|
because (due to lack of a copy_keyblock function) we need to store
|
||||||
|
an image of the keyblock which is fortunately instantly available
|
||||||
|
for keyboxes. */
|
||||||
|
enum keyblock_cache_states {
|
||||||
|
KEYBLOCK_CACHE_EMPTY,
|
||||||
|
KEYBLOCK_CACHE_PREPARED,
|
||||||
|
KEYBLOCK_CACHE_FILLED
|
||||||
|
};
|
||||||
|
|
||||||
|
struct keyblock_cache {
|
||||||
|
enum keyblock_cache_states state;
|
||||||
|
byte fpr[MAX_FINGERPRINT_LEN];
|
||||||
|
iobuf_t iobuf; /* Image of the keyblock. */
|
||||||
|
u32 *sigstatus;
|
||||||
|
int pk_no;
|
||||||
|
int uid_no;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct keydb_handle
|
struct keydb_handle
|
||||||
{
|
{
|
||||||
/* When we locked all of the resources in ACTIVE (using keyring_lock
|
/* When we locked all of the resources in ACTIVE (using keyring_lock
|
||||||
@ -94,6 +116,10 @@ struct keydb_handle
|
|||||||
/* The number of resources in ACTIVE. */
|
/* The number of resources in ACTIVE. */
|
||||||
int used;
|
int used;
|
||||||
|
|
||||||
|
/* Cache of the last found and parsed key block (only used for
|
||||||
|
keyboxes, not keyrings). */
|
||||||
|
struct keyblock_cache keyblock_cache;
|
||||||
|
|
||||||
/* Copy of ALL_RESOURCES when keydb_new is called. */
|
/* Copy of ALL_RESOURCES when keydb_new is called. */
|
||||||
struct resource_item active[MAX_KEYDB_RESOURCES];
|
struct resource_item active[MAX_KEYDB_RESOURCES];
|
||||||
};
|
};
|
||||||
@ -126,27 +152,6 @@ struct kid_not_found_cache_bucket
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* This is a simple cache used to return the last result of a
|
|
||||||
successful fingerprint search. This works only for keybox resources
|
|
||||||
because (due to lack of a copy_keyblock function) we need to store
|
|
||||||
an image of the keyblock which is fortunately instantly available
|
|
||||||
for keyboxes. */
|
|
||||||
enum keyblock_cache_states {
|
|
||||||
KEYBLOCK_CACHE_EMPTY,
|
|
||||||
KEYBLOCK_CACHE_PREPARED,
|
|
||||||
KEYBLOCK_CACHE_FILLED
|
|
||||||
};
|
|
||||||
|
|
||||||
struct {
|
|
||||||
enum keyblock_cache_states state;
|
|
||||||
byte fpr[MAX_FINGERPRINT_LEN];
|
|
||||||
iobuf_t iobuf; /* Image of the keyblock. */
|
|
||||||
u32 *sigstatus;
|
|
||||||
int pk_no;
|
|
||||||
int uid_no;
|
|
||||||
} keyblock_cache;
|
|
||||||
|
|
||||||
|
|
||||||
static int lock_all (KEYDB_HANDLE hd);
|
static int lock_all (KEYDB_HANDLE hd);
|
||||||
static void unlock_all (KEYDB_HANDLE hd);
|
static void unlock_all (KEYDB_HANDLE hd);
|
||||||
|
|
||||||
@ -233,13 +238,13 @@ kid_not_found_flush (void)
|
|||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
keyblock_cache_clear (void)
|
keyblock_cache_clear (struct keydb_handle *hd)
|
||||||
{
|
{
|
||||||
keyblock_cache.state = KEYBLOCK_CACHE_EMPTY;
|
hd->keyblock_cache.state = KEYBLOCK_CACHE_EMPTY;
|
||||||
xfree (keyblock_cache.sigstatus);
|
xfree (hd->keyblock_cache.sigstatus);
|
||||||
keyblock_cache.sigstatus = NULL;
|
hd->keyblock_cache.sigstatus = NULL;
|
||||||
iobuf_close (keyblock_cache.iobuf);
|
iobuf_close (hd->keyblock_cache.iobuf);
|
||||||
keyblock_cache.iobuf = NULL;
|
hd->keyblock_cache.iobuf = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1124,23 +1129,23 @@ keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb)
|
|||||||
if (DBG_CLOCK)
|
if (DBG_CLOCK)
|
||||||
log_clock ("keydb_get_keybock enter");
|
log_clock ("keydb_get_keybock enter");
|
||||||
|
|
||||||
if (keyblock_cache.state == KEYBLOCK_CACHE_FILLED)
|
if (hd->keyblock_cache.state == KEYBLOCK_CACHE_FILLED)
|
||||||
{
|
{
|
||||||
err = iobuf_seek (keyblock_cache.iobuf, 0);
|
err = iobuf_seek (hd->keyblock_cache.iobuf, 0);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
log_error ("keydb_get_keyblock: failed to rewind iobuf for cache\n");
|
log_error ("keydb_get_keyblock: failed to rewind iobuf for cache\n");
|
||||||
keyblock_cache_clear ();
|
keyblock_cache_clear (hd);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
err = parse_keyblock_image (keyblock_cache.iobuf,
|
err = parse_keyblock_image (hd->keyblock_cache.iobuf,
|
||||||
keyblock_cache.pk_no,
|
hd->keyblock_cache.pk_no,
|
||||||
keyblock_cache.uid_no,
|
hd->keyblock_cache.uid_no,
|
||||||
keyblock_cache.sigstatus,
|
hd->keyblock_cache.sigstatus,
|
||||||
ret_kb);
|
ret_kb);
|
||||||
if (err)
|
if (err)
|
||||||
keyblock_cache_clear ();
|
keyblock_cache_clear (hd);
|
||||||
if (DBG_CLOCK)
|
if (DBG_CLOCK)
|
||||||
log_clock (err? "keydb_get_keyblock leave (cached, failed)"
|
log_clock (err? "keydb_get_keyblock leave (cached, failed)"
|
||||||
: "keydb_get_keyblock leave (cached)");
|
: "keydb_get_keyblock leave (cached)");
|
||||||
@ -1171,13 +1176,13 @@ keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb)
|
|||||||
{
|
{
|
||||||
err = parse_keyblock_image (iobuf, pk_no, uid_no, sigstatus,
|
err = parse_keyblock_image (iobuf, pk_no, uid_no, sigstatus,
|
||||||
ret_kb);
|
ret_kb);
|
||||||
if (!err && keyblock_cache.state == KEYBLOCK_CACHE_PREPARED)
|
if (!err && hd->keyblock_cache.state == KEYBLOCK_CACHE_PREPARED)
|
||||||
{
|
{
|
||||||
keyblock_cache.state = KEYBLOCK_CACHE_FILLED;
|
hd->keyblock_cache.state = KEYBLOCK_CACHE_FILLED;
|
||||||
keyblock_cache.sigstatus = sigstatus;
|
hd->keyblock_cache.sigstatus = sigstatus;
|
||||||
keyblock_cache.iobuf = iobuf;
|
hd->keyblock_cache.iobuf = iobuf;
|
||||||
keyblock_cache.pk_no = pk_no;
|
hd->keyblock_cache.pk_no = pk_no;
|
||||||
keyblock_cache.uid_no = uid_no;
|
hd->keyblock_cache.uid_no = uid_no;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1189,8 +1194,8 @@ keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keyblock_cache.state != KEYBLOCK_CACHE_FILLED)
|
if (hd->keyblock_cache.state != KEYBLOCK_CACHE_FILLED)
|
||||||
keyblock_cache_clear ();
|
keyblock_cache_clear (hd);
|
||||||
|
|
||||||
if (DBG_CLOCK)
|
if (DBG_CLOCK)
|
||||||
log_clock (err? "keydb_get_keyblock leave (failed)"
|
log_clock (err? "keydb_get_keyblock leave (failed)"
|
||||||
@ -1298,7 +1303,7 @@ keydb_update_keyblock (KEYDB_HANDLE hd, kbnode_t kb)
|
|||||||
return gpg_error (GPG_ERR_INV_ARG);
|
return gpg_error (GPG_ERR_INV_ARG);
|
||||||
|
|
||||||
kid_not_found_flush ();
|
kid_not_found_flush ();
|
||||||
keyblock_cache_clear ();
|
keyblock_cache_clear (hd);
|
||||||
|
|
||||||
if (hd->found < 0 || hd->found >= hd->used)
|
if (hd->found < 0 || hd->found >= hd->used)
|
||||||
return gpg_error (GPG_ERR_VALUE_NOT_FOUND);
|
return gpg_error (GPG_ERR_VALUE_NOT_FOUND);
|
||||||
@ -1349,7 +1354,7 @@ keydb_insert_keyblock (KEYDB_HANDLE hd, kbnode_t kb)
|
|||||||
return gpg_error (GPG_ERR_INV_ARG);
|
return gpg_error (GPG_ERR_INV_ARG);
|
||||||
|
|
||||||
kid_not_found_flush ();
|
kid_not_found_flush ();
|
||||||
keyblock_cache_clear ();
|
keyblock_cache_clear (hd);
|
||||||
|
|
||||||
if (opt.dry_run)
|
if (opt.dry_run)
|
||||||
return 0;
|
return 0;
|
||||||
@ -1409,7 +1414,7 @@ keydb_delete_keyblock (KEYDB_HANDLE hd)
|
|||||||
return gpg_error (GPG_ERR_INV_ARG);
|
return gpg_error (GPG_ERR_INV_ARG);
|
||||||
|
|
||||||
kid_not_found_flush ();
|
kid_not_found_flush ();
|
||||||
keyblock_cache_clear ();
|
keyblock_cache_clear (hd);
|
||||||
|
|
||||||
if (hd->found < 0 || hd->found >= hd->used)
|
if (hd->found < 0 || hd->found >= hd->used)
|
||||||
return gpg_error (GPG_ERR_VALUE_NOT_FOUND);
|
return gpg_error (GPG_ERR_VALUE_NOT_FOUND);
|
||||||
@ -1497,8 +1502,6 @@ keydb_rebuild_caches (int noisy)
|
|||||||
{
|
{
|
||||||
int i, rc;
|
int i, rc;
|
||||||
|
|
||||||
keyblock_cache_clear ();
|
|
||||||
|
|
||||||
for (i=0; i < used_resources; i++)
|
for (i=0; i < used_resources; i++)
|
||||||
{
|
{
|
||||||
if (!keyring_is_writable (all_resources[i].token))
|
if (!keyring_is_writable (all_resources[i].token))
|
||||||
@ -1537,7 +1540,7 @@ keydb_search_reset (KEYDB_HANDLE hd)
|
|||||||
if (!hd)
|
if (!hd)
|
||||||
return gpg_error (GPG_ERR_INV_ARG);
|
return gpg_error (GPG_ERR_INV_ARG);
|
||||||
|
|
||||||
keyblock_cache_clear ();
|
keyblock_cache_clear (hd);
|
||||||
|
|
||||||
if (DBG_CLOCK)
|
if (DBG_CLOCK)
|
||||||
log_clock ("keydb_search_reset");
|
log_clock ("keydb_search_reset");
|
||||||
@ -1652,8 +1655,8 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
|
|||||||
&& ndesc == 1
|
&& ndesc == 1
|
||||||
&& (desc[0].mode == KEYDB_SEARCH_MODE_FPR20
|
&& (desc[0].mode == KEYDB_SEARCH_MODE_FPR20
|
||||||
|| desc[0].mode == KEYDB_SEARCH_MODE_FPR)
|
|| desc[0].mode == KEYDB_SEARCH_MODE_FPR)
|
||||||
&& keyblock_cache.state == KEYBLOCK_CACHE_FILLED
|
&& hd->keyblock_cache.state == KEYBLOCK_CACHE_FILLED
|
||||||
&& !memcmp (keyblock_cache.fpr, desc[0].u.fpr, 20))
|
&& !memcmp (hd->keyblock_cache.fpr, desc[0].u.fpr, 20))
|
||||||
{
|
{
|
||||||
/* (DESCINDEX is already set). */
|
/* (DESCINDEX is already set). */
|
||||||
if (DBG_CLOCK)
|
if (DBG_CLOCK)
|
||||||
@ -1694,14 +1697,14 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
|
|||||||
? gpg_error (GPG_ERR_NOT_FOUND)
|
? gpg_error (GPG_ERR_NOT_FOUND)
|
||||||
: rc);
|
: rc);
|
||||||
|
|
||||||
keyblock_cache_clear ();
|
keyblock_cache_clear (hd);
|
||||||
if (!hd->no_caching
|
if (!hd->no_caching
|
||||||
&& !rc
|
&& !rc
|
||||||
&& ndesc == 1 && (desc[0].mode == KEYDB_SEARCH_MODE_FPR20
|
&& ndesc == 1 && (desc[0].mode == KEYDB_SEARCH_MODE_FPR20
|
||||||
|| desc[0].mode == KEYDB_SEARCH_MODE_FPR))
|
|| desc[0].mode == KEYDB_SEARCH_MODE_FPR))
|
||||||
{
|
{
|
||||||
keyblock_cache.state = KEYBLOCK_CACHE_PREPARED;
|
hd->keyblock_cache.state = KEYBLOCK_CACHE_PREPARED;
|
||||||
memcpy (keyblock_cache.fpr, desc[0].u.fpr, 20);
|
memcpy (hd->keyblock_cache.fpr, desc[0].u.fpr, 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND
|
if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND
|
||||||
|
Loading…
x
Reference in New Issue
Block a user