aboutsummaryrefslogtreecommitdiffstats
path: root/src/spf.c
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2014-01-27 16:12:27 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2014-01-27 16:12:27 +0000
commit9bb4dcceadb7f78efe946946ccf7742a8c6e4f50 (patch)
tree70c25bfdf8bffbb6ac5eb424a20f9bba871612ee /src/spf.c
parent15b1bddab547189e5fbdcb4441b2d64e4c8f10aa (diff)
downloadrspamd-9bb4dcceadb7f78efe946946ccf7742a8c6e4f50.tar.gz
rspamd-9bb4dcceadb7f78efe946946ccf7742a8c6e4f50.zip
Rework resolver library.
Diffstat (limited to 'src/spf.c')
-rw-r--r--src/spf.c263
1 files changed, 127 insertions, 136 deletions
diff --git a/src/spf.c b/src/spf.c
index e394005b8..f04395da5 100644
--- a/src/spf.c
+++ b/src/spf.c
@@ -391,8 +391,8 @@ spf_record_dns_callback (struct rspamd_dns_reply *reply, gpointer arg)
{
struct spf_dns_cb *cb = arg;
gchar *begin;
- union rspamd_reply_element *elt_data;
- GList *tmp = NULL, *elt;
+ struct rspamd_reply_entry *elt_data;
+ GList *tmp = NULL;
struct worker_task *task;
struct spf_addr *new_addr;
@@ -401,165 +401,160 @@ spf_record_dns_callback (struct rspamd_dns_reply *reply, gpointer arg)
cb->rec->requests_inflight --;
if (reply->code == DNS_RC_NOERROR) {
- if (reply->elements != NULL) {
- /* Add all logic for all DNS states here */
- elt = reply->elements;
- while (elt) {
- elt_data = elt->data;
- switch (cb->cur_action) {
- case SPF_RESOLVE_MX:
- if (reply->type == DNS_REQUEST_MX) {
- /* Now resolve A record for this MX */
- if (make_dns_request (task->resolver, task->s, task->task_pool,
- spf_record_dns_callback, (void *)cb, DNS_REQUEST_A, elt_data->mx.name)) {
- task->dns_requests ++;
- cb->rec->requests_inflight ++;
- }
+ /* Add all logic for all DNS states here */
+ LL_FOREACH (reply->entries, elt_data) {
+ switch (cb->cur_action) {
+ case SPF_RESOLVE_MX:
+ if (elt_data->type == DNS_REQUEST_MX) {
+ /* Now resolve A record for this MX */
+ if (make_dns_request (task->resolver, task->s, task->task_pool,
+ spf_record_dns_callback, (void *)cb, DNS_REQUEST_A, elt_data->content.mx.name)) {
+ task->dns_requests ++;
+ cb->rec->requests_inflight ++;
+ }
+ }
+ else if (elt_data->type == DNS_REQUEST_A) {
+ if (!cb->addr->data.normal.parsed) {
+ cb->addr->data.normal.d.in4.s_addr = elt_data->content.a.addr.s_addr;
+ cb->addr->data.normal.mask = 32;
+ cb->addr->data.normal.parsed = TRUE;
}
- else if (reply->type == DNS_REQUEST_A) {
- if (!cb->addr->data.normal.parsed) {
- cb->addr->data.normal.d.in4.s_addr = elt_data->a.addr[0].s_addr;
- cb->addr->data.normal.mask = 32;
- cb->addr->data.normal.parsed = TRUE;
+ else {
+ /* Insert one more address */
+ tmp = spf_addr_find (cb->rec->addrs, cb->addr);
+ if (tmp) {
+ new_addr = memory_pool_alloc (task->task_pool, sizeof (struct spf_addr));
+ memcpy (new_addr, cb->addr, sizeof (struct spf_addr));
+ new_addr->data.normal.d.in4.s_addr = elt_data->content.a.addr.s_addr;
+ new_addr->data.normal.parsed = TRUE;
+ cb->rec->addrs = g_list_insert_before (cb->rec->addrs, tmp, new_addr);
}
else {
- /* Insert one more address */
- tmp = spf_addr_find (cb->rec->addrs, cb->addr);
- if (tmp) {
- new_addr = memory_pool_alloc (task->task_pool, sizeof (struct spf_addr));
- memcpy (new_addr, cb->addr, sizeof (struct spf_addr));
- new_addr->data.normal.d.in4.s_addr = elt_data->a.addr[0].s_addr;
- new_addr->data.normal.parsed = TRUE;
- cb->rec->addrs = g_list_insert_before (cb->rec->addrs, tmp, new_addr);
- }
- else {
- msg_info ("<%s>: spf error for domain %s: addresses mismatch",
- task->message_id, cb->rec->sender_domain);
- }
+ msg_info ("<%s>: spf error for domain %s: addresses mismatch",
+ task->message_id, cb->rec->sender_domain);
}
-
}
+
+ }
#ifdef HAVE_INET_PTON
- else if (reply->type == DNS_REQUEST_AAA) {
- if (!cb->addr->data.normal.parsed) {
- memcpy (&cb->addr->data.normal.d.in6, &elt_data->aaa.addr, sizeof (struct in6_addr));
- cb->addr->data.normal.mask = 32;
- cb->addr->data.normal.parsed = TRUE;
- cb->addr->data.normal.ipv6 = TRUE;
+ else if (elt_data->type == DNS_REQUEST_AAA) {
+ if (!cb->addr->data.normal.parsed) {
+ memcpy (&cb->addr->data.normal.d.in6, &elt_data->content.aaa.addr, sizeof (struct in6_addr));
+ cb->addr->data.normal.mask = 32;
+ cb->addr->data.normal.parsed = TRUE;
+ cb->addr->data.normal.ipv6 = TRUE;
+ }
+ else {
+ /* Insert one more address */
+ tmp = spf_addr_find (cb->rec->addrs, cb->addr);
+ if (tmp) {
+ new_addr = memory_pool_alloc (task->task_pool, sizeof (struct spf_addr));
+ memcpy (new_addr, cb->addr, sizeof (struct spf_addr));
+ memcpy (&new_addr->data.normal.d.in6, &elt_data->content.aaa.addr, sizeof (struct in6_addr));
+ new_addr->data.normal.parsed = TRUE;
+ new_addr->data.normal.ipv6 = TRUE;
+ cb->rec->addrs = g_list_insert_before (cb->rec->addrs, tmp, new_addr);
}
else {
- /* Insert one more address */
- tmp = spf_addr_find (cb->rec->addrs, cb->addr);
- if (tmp) {
- new_addr = memory_pool_alloc (task->task_pool, sizeof (struct spf_addr));
- memcpy (new_addr, cb->addr, sizeof (struct spf_addr));
- memcpy (&new_addr->data.normal.d.in6, &elt_data->aaa.addr, sizeof (struct in6_addr));
- new_addr->data.normal.parsed = TRUE;
- new_addr->data.normal.ipv6 = TRUE;
- cb->rec->addrs = g_list_insert_before (cb->rec->addrs, tmp, new_addr);
- }
- else {
- msg_info ("<%s>: spf error for domain %s: addresses mismatch",
- task->message_id, cb->rec->sender_domain);
- }
+ msg_info ("<%s>: spf error for domain %s: addresses mismatch",
+ task->message_id, cb->rec->sender_domain);
}
-
}
+
+ }
#endif
- break;
- case SPF_RESOLVE_A:
- if (reply->type == DNS_REQUEST_A) {
- /* XXX: process only one record */
- cb->addr->data.normal.d.in4.s_addr = elt_data->a.addr[0].s_addr;
- cb->addr->data.normal.mask = 32;
- cb->addr->data.normal.parsed = TRUE;
- }
+ break;
+ case SPF_RESOLVE_A:
+ if (elt_data->type == DNS_REQUEST_A) {
+ /* XXX: process only one record */
+ cb->addr->data.normal.d.in4.s_addr = elt_data->content.a.addr.s_addr;
+ cb->addr->data.normal.mask = 32;
+ cb->addr->data.normal.parsed = TRUE;
+ }
#ifdef HAVE_INET_PTON
- else if (reply->type == DNS_REQUEST_AAA) {
- memcpy (&cb->addr->data.normal.d.in6, &elt_data->aaa.addr, sizeof (struct in6_addr));
- cb->addr->data.normal.mask = 32;
- cb->addr->data.normal.parsed = TRUE;
- cb->addr->data.normal.ipv6 = TRUE;
- }
+ else if (elt_data->type == DNS_REQUEST_AAA) {
+ memcpy (&cb->addr->data.normal.d.in6, &elt_data->content.aaa.addr, sizeof (struct in6_addr));
+ cb->addr->data.normal.mask = 32;
+ cb->addr->data.normal.parsed = TRUE;
+ cb->addr->data.normal.ipv6 = TRUE;
+ }
#endif
- break;
+ break;
#ifdef HAVE_INET_PTON
- case SPF_RESOLVE_AAA:
- if (reply->type == DNS_REQUEST_A) {
- /* XXX: process only one record */
- cb->addr->data.normal.d.in4.s_addr = elt_data->a.addr[0].s_addr;
- cb->addr->data.normal.mask = 32;
- cb->addr->data.normal.parsed = TRUE;
- }
- else if (reply->type == DNS_REQUEST_AAA) {
- memcpy (&cb->addr->data.normal.d.in6, &elt_data->aaa.addr, sizeof (struct in6_addr));
- cb->addr->data.normal.mask = 32;
- cb->addr->data.normal.parsed = TRUE;
- cb->addr->data.normal.ipv6 = TRUE;
- }
+ case SPF_RESOLVE_AAA:
+ if (elt_data->type == DNS_REQUEST_A) {
+ /* XXX: process only one record */
+ cb->addr->data.normal.d.in4.s_addr = elt_data->content.a.addr.s_addr;
+ cb->addr->data.normal.mask = 32;
+ cb->addr->data.normal.parsed = TRUE;
+ }
+ else if (elt_data->type == DNS_REQUEST_AAA) {
+ memcpy (&cb->addr->data.normal.d.in6, &elt_data->content.aaa.addr, sizeof (struct in6_addr));
+ cb->addr->data.normal.mask = 32;
+ cb->addr->data.normal.parsed = TRUE;
+ cb->addr->data.normal.ipv6 = TRUE;
+ }
#endif
- break;
- case SPF_RESOLVE_PTR:
- break;
- case SPF_RESOLVE_REDIRECT:
- if (reply->type == DNS_REQUEST_TXT) {
- begin = elt_data->txt.data;
-
- if (!cb->in_include && cb->rec->addrs) {
- g_list_free (cb->rec->addrs);
- cb->rec->addrs = NULL;
- }
- start_spf_parse (cb->rec, begin);
+ break;
+ case SPF_RESOLVE_PTR:
+ break;
+ case SPF_RESOLVE_REDIRECT:
+ if (elt_data->type == DNS_REQUEST_TXT) {
+ begin = elt_data->content.txt.data;
+ if (!cb->in_include && cb->rec->addrs) {
+ g_list_free (cb->rec->addrs);
+ cb->rec->addrs = NULL;
}
- break;
- case SPF_RESOLVE_INCLUDE:
- if (reply->type == DNS_REQUEST_TXT) {
- begin = elt_data->txt.data;
+ start_spf_parse (cb->rec, begin);
+
+ }
+ break;
+ case SPF_RESOLVE_INCLUDE:
+ if (elt_data->type == DNS_REQUEST_TXT) {
+ begin = elt_data->content.txt.data;
#ifdef SPF_DEBUG
- msg_info ("before include");
- dump_spf_record (cb->rec->addrs);
+ msg_info ("before include");
+ dump_spf_record (cb->rec->addrs);
#endif
- tmp = cb->rec->addrs;
- cb->rec->addrs = NULL;
- cb->rec->in_include = TRUE;
- start_spf_parse (cb->rec, begin);
- cb->rec->in_include = FALSE;
+ tmp = cb->rec->addrs;
+ cb->rec->addrs = NULL;
+ cb->rec->in_include = TRUE;
+ start_spf_parse (cb->rec, begin);
+ cb->rec->in_include = FALSE;
#ifdef SPF_DEBUG
- msg_info ("after include");
- dump_spf_record (cb->rec->addrs);
+ msg_info ("after include");
+ dump_spf_record (cb->rec->addrs);
#endif
- /* Insert new list */
- cb->addr->is_list = TRUE;
- cb->addr->data.list = cb->rec->addrs;
- cb->rec->addrs = tmp;
- }
- break;
- case SPF_RESOLVE_EXP:
- break;
- case SPF_RESOLVE_EXISTS:
- if (reply->type == DNS_REQUEST_A) {
- /* If specified address resolves, we can accept connection from every IP */
- cb->addr->data.normal.d.in4.s_addr = INADDR_NONE;
- cb->addr->data.normal.mask = 0;
- }
- break;
+ /* Insert new list */
+ cb->addr->is_list = TRUE;
+ cb->addr->data.list = cb->rec->addrs;
+ cb->rec->addrs = tmp;
+ }
+ break;
+ case SPF_RESOLVE_EXP:
+ break;
+ case SPF_RESOLVE_EXISTS:
+ if (elt_data->type == DNS_REQUEST_A) {
+ /* If specified address resolves, we can accept connection from every IP */
+ cb->addr->data.normal.d.in4.s_addr = INADDR_NONE;
+ cb->addr->data.normal.mask = 0;
}
- elt = g_list_next (elt);
+ break;
}
}
}
else if (reply->code == DNS_RC_NXDOMAIN) {
switch (cb->cur_action) {
case SPF_RESOLVE_MX:
- if (reply->type == DNS_REQUEST_MX) {
+ if (reply->request->type == DNS_REQUEST_MX) {
msg_info ("<%s>: spf error for domain %s: cannot find MX record for %s",
task->message_id, cb->rec->sender_domain, cb->rec->cur_domain);
cb->addr->data.normal.d.in4.s_addr = INADDR_NONE;
cb->addr->data.normal.mask = 32;
}
- else if (reply->type != DNS_REQUEST_MX) {
+ else if (reply->request->type != DNS_REQUEST_MX) {
msg_info ("<%s>: spf error for domain %s: cannot resolve MX record for %s",
task->message_id, cb->rec->sender_domain, cb->rec->cur_domain);
cb->addr->data.normal.d.in4.s_addr = INADDR_NONE;
@@ -567,7 +562,7 @@ spf_record_dns_callback (struct rspamd_dns_reply *reply, gpointer arg)
}
break;
case SPF_RESOLVE_A:
- if (reply->type == DNS_REQUEST_A) {
+ if (reply->request->type == DNS_REQUEST_A) {
/* XXX: process only one record */
cb->addr->data.normal.d.in4.s_addr = INADDR_NONE;
cb->addr->data.normal.mask = 32;
@@ -575,7 +570,7 @@ spf_record_dns_callback (struct rspamd_dns_reply *reply, gpointer arg)
break;
#ifdef HAVE_INET_PTON
case SPF_RESOLVE_AAA:
- if (reply->type == DNS_REQUEST_AAA) {
+ if (reply->request->type == DNS_REQUEST_AAA) {
/* XXX: process only one record */
memset (&cb->addr->data.normal.d.in6, 0xff, sizeof (struct in6_addr));
cb->addr->data.normal.mask = 32;
@@ -1345,16 +1340,12 @@ static void
spf_dns_callback (struct rspamd_dns_reply *reply, gpointer arg)
{
struct spf_record *rec = arg;
- union rspamd_reply_element *elt;
- GList *cur;
+ struct rspamd_reply_entry *elt;
rec->requests_inflight --;
if (reply->code == DNS_RC_NOERROR) {
- cur = reply->elements;
- while (cur) {
- elt = cur->data;
- start_spf_parse (rec, elt->txt.data);
- cur = g_list_next (cur);
+ LL_FOREACH (reply->entries, elt) {
+ start_spf_parse (rec, elt->content.txt.data);
}
}