*/
/*
- * $Id: tsig.c,v 1.138.136.2 2010/03/12 23:49:56 tbox Exp $
+ * $Id: tsig.c,v 1.138.136.3 2010/07/09 05:14:08 each Exp $
*/
/*! \file */
#include <config.h>
#include <isc/mem.h>
#include <isc/print.h>
#include <isc/refcount.h>
+#include <isc/serial.h>
#include <isc/string.h> /* Required for HP/UX (and others?) */
#include <isc/util.h>
#include <isc/time.h>
#define TSIG_MAGIC ISC_MAGIC('T', 'S', 'I', 'G')
#define VALID_TSIG_KEY(x) ISC_MAGIC_VALID(x, TSIG_MAGIC)
+#ifndef DNS_TSIG_MAXGENERATEDKEYS
+#define DNS_TSIG_MAXGENERATEDKEYS 4096
+#endif
+
#define is_response(msg) (msg->flags & DNS_MESSAGEFLAG_QR)
#define algname_is_allocated(algname) \
((algname) != dns_tsig_hmacmd5_name && \
level, "tsig key '%s': %s", namestr, message);
}
+static void
+remove_fromring(dns_tsigkey_t *tkey) {
+ if (tkey->generated) {
+ ISC_LIST_UNLINK(tkey->ring->lru, tkey, link);
+ tkey->ring->generated--;
+ }
+ (void)dns_rbt_deletename(tkey->ring->keys, &tkey->name, ISC_FALSE);
+}
+
+static void
+adjust_lru(dns_tsigkey_t *tkey) {
+ if (tkey->generated) {
+ RWLOCK(&tkey->ring->lock, isc_rwlocktype_write);
+ /*
+ * We may have been removed from the LRU list between
+ * removing the read lock and aquiring the write lock.
+ */
+ if (ISC_LINK_LINKED(tkey, link)) {
+ ISC_LIST_UNLINK(tkey->ring->lru, tkey, link);
+ ISC_LIST_APPEND(tkey->ring->lru, tkey, link);
+ }
+ RWUNLOCK(&tkey->ring->lock, isc_rwlocktype_write);
+ }
+}
+
/*
* A supplemental routine just to add a key to ring. Note that reference
* counter should be counted separately because we may be adding the key
}
result = dns_rbt_addname(ring->keys, name, tkey);
+ if (tkey->generated) {
+ /*
+ * Add the new key to the LRU list and remove the least
+ * recently used key if there are too many keys on the list.
+ */
+ ISC_LIST_INITANDAPPEND(ring->lru, tkey, link);
+ if (ring->generated++ > ring->maxgenerated)
+ remove_fromring(ISC_LIST_HEAD(ring->lru));
+ }
RWUNLOCK(&ring->lock, isc_rwlocktype_write);
return (result);
tsig_log(tkey, 2, "tsig expire: deleting");
/* delete the key */
dns_rbtnodechain_invalidate(&chain);
- (void)dns_rbt_deletename(ring->keys,
- &tkey->name,
- ISC_FALSE);
+ remove_fromring(tkey);
goto again;
}
}
dns_rbtnodechain_invalidate(&chain);
return;
}
-
}
}
REQUIRE(key->ring != NULL);
RWLOCK(&key->ring->lock, isc_rwlocktype_write);
- (void)dns_rbt_deletename(key->ring->keys, &key->name, ISC_FALSE);
+ remove_fromring(key);
RWUNLOCK(&key->ring->lock, isc_rwlocktype_write);
}
RWUNLOCK(&ring->lock, isc_rwlocktype_read);
return (ISC_R_NOTFOUND);
}
- if (key->inception != key->expire && key->expire < now) {
+ if (key->inception != key->expire && isc_serial_lt(key->expire, now)) {
/*
* The key has expired.
*/
RWUNLOCK(&ring->lock, isc_rwlocktype_read);
RWLOCK(&ring->lock, isc_rwlocktype_write);
- (void)dns_rbt_deletename(ring->keys, name, ISC_FALSE);
+ remove_fromring(key);
RWUNLOCK(&ring->lock, isc_rwlocktype_write);
return (ISC_R_NOTFOUND);
}
-
+#if 0
+ /*
+ * MPAXXX We really should look at the inception time.
+ */
+ if (key->inception != key->expire &&
+ isc_serial_lt(key->inception, now)) {
+ RWUNLOCK(&ring->lock, isc_rwlocktype_read);
+ adjust_lru(key);
+ return (ISC_R_NOTFOUND);
+ }
+#endif
isc_refcount_increment(&key->refs, NULL);
RWUNLOCK(&ring->lock, isc_rwlocktype_read);
+ adjust_lru(key);
*tsigkey = key;
return (ISC_R_SUCCESS);
}
ring->writecount = 0;
ring->mctx = NULL;
+ ring->generated = 0;
+ ring->maxgenerated = DNS_TSIG_MAXGENERATEDKEYS;
+ ISC_LIST_INIT(ring->lru);
isc_mem_attach(mctx, &ring->mctx);
*ringp = ring;