diff options
-rw-r--r-- | src/libserver/spf.c | 101 | ||||
-rw-r--r-- | src/libserver/spf.h | 8 |
2 files changed, 64 insertions, 45 deletions
diff --git a/src/libserver/spf.c b/src/libserver/spf.c index 0c4a8518b..c91cc5245 100644 --- a/src/libserver/spf.c +++ b/src/libserver/spf.c @@ -137,23 +137,30 @@ struct spf_dns_cb { unsigned eyeballs_errors; /* number of DNS subrequests errored */ }; +static inline bool +spf_record_can_dns(const struct spf_record *rec) +{ + if (spf_lib_ctx->max_dns_nesting > 0 && + rec->nested > spf_lib_ctx->max_dns_nesting) { + msg_warn_spf("spf nesting limit: %d > %d is reached, domain: %s", + rec->nested, spf_lib_ctx->max_dns_nesting, + rec->sender_domain); + return false; + } + if (spf_lib_ctx->max_dns_requests > 0 && + rec->dns_requests > spf_lib_ctx->max_dns_requests) { + msg_warn_spf("spf dns requests limit: %d > %d is reached, domain: %s", + rec->dns_requests, spf_lib_ctx->max_dns_requests, + rec->sender_domain); + return false; + } -#define CHECK_REC(rec) \ - do { \ - if (spf_lib_ctx->max_dns_nesting > 0 && \ - (rec)->nested > spf_lib_ctx->max_dns_nesting) { \ - msg_warn_spf("spf nesting limit: %d > %d is reached, domain: %s", \ - (rec)->nested, spf_lib_ctx->max_dns_nesting, \ - (rec)->sender_domain); \ - return FALSE; \ - } \ - if (spf_lib_ctx->max_dns_requests > 0 && \ - (rec)->dns_requests > spf_lib_ctx->max_dns_requests) { \ - msg_warn_spf("spf dns requests limit: %d > %d is reached, domain: %s", \ - (rec)->dns_requests, spf_lib_ctx->max_dns_requests, \ - (rec)->sender_domain); \ - return FALSE; \ - } \ + return true; +} + +#define CHECK_REC(rec) \ + do { \ + if (!spf_record_can_dns(rec)) return FALSE; \ } while (0) RSPAMD_CONSTRUCTOR(rspamd_spf_lib_ctx_ctor) @@ -179,7 +186,7 @@ spf_record_cached_unref_dtor(gpointer p) { struct spf_resolved *flat = (struct spf_resolved *) p; - _spf_record_unref(flat, "LRU cache"); + spf_record_unref_internal(flat, "LRU cache"); } void spf_library_config(const ucl_object_t *obj) @@ -908,25 +915,31 @@ spf_record_dns_callback(struct rdns_reply *reply, gpointer arg) /* Now resolve A record for this MX */ msg_debug_spf("resolve %s after resolving of MX", elt_data->content.mx.name); - if (rspamd_dns_resolver_request_task_forced(task, - spf_record_dns_callback, (void *) cb, - RDNS_REQUEST_A, - elt_data->content.mx.name)) { - cb->rec->requests_inflight++; - cb->eyeballs_sent++; - } - - if (!spf_lib_ctx->disable_ipv6) { + if (spf_record_can_dns(rec)) { if (rspamd_dns_resolver_request_task_forced(task, spf_record_dns_callback, (void *) cb, - RDNS_REQUEST_AAAA, + RDNS_REQUEST_A, elt_data->content.mx.name)) { cb->rec->requests_inflight++; cb->eyeballs_sent++; } + + if (!spf_lib_ctx->disable_ipv6) { + if (rspamd_dns_resolver_request_task_forced(task, + spf_record_dns_callback, (void *) cb, + RDNS_REQUEST_AAAA, + elt_data->content.mx.name)) { + cb->rec->requests_inflight++; + cb->eyeballs_sent++; + } + } + else { + msg_debug_spf("skip AAAA request for MX resolution"); + } } else { - msg_debug_spf("skip AAAA request for MX resolution"); + /* Max DNS requests reached */ + cb->addr->flags |= RSPAMD_SPF_FLAG_PERMFAIL; } } else { @@ -951,25 +964,31 @@ spf_record_dns_callback(struct rdns_reply *reply, gpointer arg) elt_data->content.ptr.name)) { msg_debug_spf("resolve PTR %s after resolving of PTR", elt_data->content.ptr.name); - if (rspamd_dns_resolver_request_task_forced(task, - spf_record_dns_callback, (void *) cb, - RDNS_REQUEST_A, - elt_data->content.ptr.name)) { - cb->rec->requests_inflight++; - cb->eyeballs_sent++; - } - - if (!spf_lib_ctx->disable_ipv6) { + if (spf_record_can_dns(rec)) { if (rspamd_dns_resolver_request_task_forced(task, spf_record_dns_callback, (void *) cb, - RDNS_REQUEST_AAAA, + RDNS_REQUEST_A, elt_data->content.ptr.name)) { cb->rec->requests_inflight++; cb->eyeballs_sent++; } + + if (!spf_lib_ctx->disable_ipv6) { + if (rspamd_dns_resolver_request_task_forced(task, + spf_record_dns_callback, (void *) cb, + RDNS_REQUEST_AAAA, + elt_data->content.ptr.name)) { + cb->rec->requests_inflight++; + cb->eyeballs_sent++; + } + } + else { + msg_debug_spf("skip AAAA request for PTR resolution"); + } } else { - msg_debug_spf("skip AAAA request for PTR resolution"); + /* Max DNS requests reached */ + cb->addr->flags |= RSPAMD_SPF_FLAG_PERMFAIL; } } else { @@ -2719,13 +2738,13 @@ rspamd_spf_resolve(struct rspamd_task *task, spf_cb_t callback, } struct spf_resolved * -_spf_record_ref(struct spf_resolved *flat, const char *loc) +spf_record_ref_internal(struct spf_resolved *flat, const char *loc) { REF_RETAIN(flat); return flat; } -void _spf_record_unref(struct spf_resolved *flat, const char *loc) +void spf_record_unref_internal(struct spf_resolved *flat, const char *loc) { REF_RELEASE(flat); } diff --git a/src/libserver/spf.h b/src/libserver/spf.h index b89dc4d0e..9c133e266 100644 --- a/src/libserver/spf.h +++ b/src/libserver/spf.h @@ -142,15 +142,15 @@ struct rspamd_spf_cred *rspamd_spf_get_cred(struct rspamd_task *task); /* * Increase refcount */ -struct spf_resolved *_spf_record_ref(struct spf_resolved *rec, const char *loc); +struct spf_resolved *spf_record_ref_internal(struct spf_resolved *rec, const char *loc); #define spf_record_ref(rec) \ - _spf_record_ref((rec), G_STRLOC) + spf_record_ref_internal((rec), G_STRLOC) /* * Decrease refcount */ -void _spf_record_unref(struct spf_resolved *rec, const char *loc); +void spf_record_unref_internal(struct spf_resolved *rec, const char *loc); #define spf_record_unref(rec) \ - _spf_record_unref((rec), G_STRLOC) + spf_record_unref_internal((rec), G_STRLOC) /** * Prints address + mask in a freshly allocated string (must be freed) |