if (elt->type == DNS_REQUEST_TXT) {
key = rspamd_dkim_parse_key (elt->content.txt.data, &keylen, &err);
if (key) {
+ key->ttl = elt->ttl;
break;
}
}
guint8 *keydata;
guint keylen;
gsize decoded_len;
+ guint ttl;
#ifdef HAVE_OPENSSL
RSA *key_rsa;
BIO *key_bio;
if (node->hash->value_destroy) {
node->hash->value_destroy (node->data);
}
-
+ g_queue_delete_link (node->hash->q, node->link);
g_slice_free1 (sizeof (rspamd_lru_element_t), node);
}
static rspamd_lru_element_t*
-rspamd_lru_create_node (rspamd_lru_hash_t *hash, gpointer key, gpointer value, time_t now)
+rspamd_lru_create_node (rspamd_lru_hash_t *hash, gpointer key, gpointer value, time_t now, guint ttl)
{
rspamd_lru_element_t *node;
node = g_slice_alloc (sizeof (rspamd_lru_element_t));
- node->hash = hash;
node->data = value;
node->key = key;
node->store_time = now;
+ node->ttl = ttl;
+ node->hash = hash;
return node;
}
rspamd_lru_element_t *res;
if ((res = hash->lookup_func (hash->storage, key)) != NULL) {
+ if (res->ttl != 0) {
+ if (now - res->store_time > res->ttl) {
+ hash->delete_func (hash->storage, key);
+ return NULL;
+ }
+ }
if (hash->maxage > 0) {
if (now - res->store_time > hash->maxage) {
+ res = g_queue_peek_tail (hash->q);
/* Expire elements from queue tail */
- res = g_queue_pop_tail (hash->q);
-
while (res != NULL && now - res->store_time > hash->maxage) {
hash->delete_func (hash->storage, res->key);
- res = g_queue_pop_tail (hash->q);
- }
- /* Restore last element */
- if (res != NULL) {
- g_queue_push_tail (hash->q, res);
+ res = g_queue_peek_tail (hash->q);
}
return NULL;
}
}
- }
-
- if (res) {
return res->data;
}
* @param value value of key
*/
void
-rspamd_lru_hash_insert (rspamd_lru_hash_t *hash, gpointer key, gpointer value, time_t now)
+rspamd_lru_hash_insert (rspamd_lru_hash_t *hash, gpointer key, gpointer value,
+ time_t now, guint ttl)
{
rspamd_lru_element_t *res;
gint removed = 0;
- if ((gint)g_queue_get_length (hash->q) >= hash->maxsize) {
- /* Expire some elements */
- res = g_queue_pop_tail (hash->q);
- if (hash->maxage > 0) {
- while (res != NULL && now - res->store_time > hash->maxage) {
+ if ((res = hash->lookup_func (hash->storage, key)) != NULL) {
+ hash->delete_func (hash->storage, res->key);
+ }
+ else {
+ if (hash->maxsize > 0 &&
+ (gint)g_queue_get_length (hash->q) >= hash->maxsize) {
+ /* Expire some elements */
+ res = g_queue_peek_tail (hash->q);
+ if (hash->maxage > 0) {
+ while (res != NULL && now - res->store_time > hash->maxage) {
+ if (res->key != NULL) {
+ hash->delete_func (hash->storage, res->key);
+ }
+ else {
+ break;
+ }
+ res = g_queue_peek_tail (hash->q);
+ removed ++;
+ }
+ }
+ if (removed == 0) {
+ /* Remove explicitly */
if (res->key != NULL) {
hash->delete_func (hash->storage, res->key);
}
- res = g_queue_pop_tail (hash->q);
- removed ++;
}
}
- /* If elements are already removed do not expire extra elements */
- if (removed != 0 && res != NULL) {
- g_queue_push_tail (hash->q, res);
- }
}
- res = rspamd_lru_create_node (hash, key, value, now);
+ res = rspamd_lru_create_node (hash, key, value, now, ttl);
hash->insert_func (hash->storage, key, res);
g_queue_push_head (hash->q, res);
+ res->link = g_queue_peek_head_link (hash->q);
}
void
gpointer data;
gpointer key;
time_t store_time;
+ guint ttl;
rspamd_lru_hash_t *hash;
+ GList *link;
} rspamd_lru_element_t;
* @param key key to insert
* @param value value of key
*/
-void rspamd_lru_hash_insert (rspamd_lru_hash_t *hash, gpointer key, gpointer value, time_t now);
+void rspamd_lru_hash_insert (rspamd_lru_hash_t *hash, gpointer key, gpointer value,
+ time_t now, guint ttl);
/**
* Remove lru hash
if (key != NULL) {
/* Add new key to the lru cache */
- rspamd_lru_hash_insert (dkim_module_ctx->dkim_hash, g_strdup (ctx->dns_key), key, task->tv.tv_sec);
+ rspamd_lru_hash_insert (dkim_module_ctx->dkim_hash, g_strdup (ctx->dns_key),
+ key, task->tv.tv_sec, key->ttl);
dkim_module_check (task, ctx, key);
}
else {
/* Insert tempfail symbol */
msg_info ("cannot get key for domain %s", ctx->dns_key);
if (err != NULL) {
- insert_result (task, dkim_module_ctx->symbol_tempfail, 1, g_list_prepend (NULL, memory_pool_strdup (task->task_pool, err->message)));
+ insert_result (task, dkim_module_ctx->symbol_tempfail, 1,
+ g_list_prepend (NULL, memory_pool_strdup (task->task_pool, err->message)));
}
else {
#endif
/* Parse signature */
msg_debug ("create dkim signature");
- /* Check only last signature as there is no way to check embeded signatures after resend or something like this */
+ /*
+ * Check only last signature as there is no way to check embeded signatures after
+ * resend or something like this
+ */
if (dkim_module_ctx->skip_multi) {
if (hlist->next != NULL) {
msg_info ("<%s> skip dkim check as it has several dkim signatures", task->message_id);
}
else {
/* Get key */
- if (dkim_module_ctx->trusted_only && (dkim_module_ctx->dkim_domains == NULL || g_hash_table_lookup (dkim_module_ctx->dkim_domains, ctx->domain) == NULL)) {
+ if (dkim_module_ctx->trusted_only && (dkim_module_ctx->dkim_domains == NULL ||
+ g_hash_table_lookup (dkim_module_ctx->dkim_domains, ctx->domain) == NULL)) {
msg_debug ("skip dkim check for %s domain", ctx->domain);
return;
}
if ((l = rspamd_lru_hash_lookup (spf_module_ctx->spf_hash, record->sender_domain, task->tv.tv_sec)) == NULL) {
l = spf_record_copy (record->addrs);
rspamd_lru_hash_insert (spf_module_ctx->spf_hash, g_strdup (record->sender_domain),
- l, task->tv.tv_sec);
+ l, task->tv.tv_sec, record->ttl);
}
spf_check_list (l, task);
}
} while (0) \
static gboolean parse_spf_record (struct worker_task *task, struct spf_record *rec);
-static void start_spf_parse (struct spf_record *rec, gchar *begin);
+static void start_spf_parse (struct spf_record *rec, gchar *begin, guint ttl);
/* Determine spf mech */
static spf_mech_t
g_list_free (cb->rec->addrs);
cb->rec->addrs = NULL;
}
- start_spf_parse (cb->rec, begin);
+ start_spf_parse (cb->rec, begin, elt_data->ttl);
}
break;
tmp = cb->rec->addrs;
cb->rec->addrs = NULL;
cb->rec->in_include = TRUE;
- start_spf_parse (cb->rec, begin);
+ start_spf_parse (cb->rec, begin, 0);
cb->rec->in_include = FALSE;
#ifdef SPF_DEBUG
}
static void
-start_spf_parse (struct spf_record *rec, gchar *begin)
+start_spf_parse (struct spf_record *rec, gchar *begin, guint ttl)
{
/* Skip spaces */
while (g_ascii_isspace (*begin)) {
memory_pool_add_destructor (rec->task->task_pool, (pool_destruct_func)g_strfreev, rec->elts);
rec->cur_elt = rec->elts[0];
while (parse_spf_record (rec->task, rec));
+ if (ttl != 0) {
+ rec->ttl = ttl;
+ }
}
}
else if (g_ascii_strncasecmp (begin, SPF_VER2_STR, sizeof (SPF_VER2_STR) - 1) == 0) {
memory_pool_add_destructor (rec->task->task_pool, (pool_destruct_func)g_strfreev, rec->elts);
rec->cur_elt = rec->elts[0];
while (parse_spf_record (rec->task, rec));
+ if (ttl != 0) {
+ rec->ttl = ttl;
+ }
}
}
else {
rec->requests_inflight --;
if (reply->code == DNS_RC_NOERROR) {
LL_FOREACH (reply->entries, elt) {
- start_spf_parse (rec, elt->content.txt.data);
+ start_spf_parse (rec, elt->content.txt.data, elt->ttl);
}
}
gint dns_requests;
gint requests_inflight;
+ guint ttl;
+
GList *addrs;
gchar *cur_domain;
gchar *sender;