static guint8 *
decompress_label (guint8 *begin, guint16 *len, guint16 max)
{
- guint16 offset;
- offset = ntohs ((*len) ^ DNS_COMPRESSION_BITS);
+ guint16 offset = DNS_COMPRESSION_BITS;
+ offset = (*len) ^ (offset << 8);
if (offset > max) {
return NULL;
}
/* This may be compressed, so we need to decompress it */
if (len1 & DNS_COMPRESSION_BITS) {
- memcpy (&len1, p, sizeof (guint16));
+ len1 = ((*p) << 8) + *(p + 1);
l1 = decompress_label (in, &len1, len);
if (l1 == NULL) {
msg_info ("invalid DNS pointer");
p += len1;
}
if (len2 & DNS_COMPRESSION_BITS) {
- memcpy (&len2, p, sizeof (guint16));
+ len2 = ((*p) << 8) + *(p + 1);
l2 = decompress_label (req->packet, &len2, len);
if (l2 == NULL) {
msg_info ("invalid DNS pointer");
}
else if (llen & DNS_COMPRESSION_BITS) {
ptrs ++;
- memcpy (&llen, p, sizeof (guint16));
+ llen = ((*p) << 8) + *(p + 1);
l = decompress_label (in, &llen, end - in);
if (l == NULL) {
msg_info ("invalid DNS pointer");
break;
}
else if (llen & DNS_COMPRESSION_BITS) {
- memcpy (&llen, p, sizeof (guint16));
+ llen = ((*p) << 8) + *(p + 1);
l = decompress_label (in, &llen, end - in);
begin = l;
length = end - begin;
*(t - 1) = '\0';
end:
if (offset < 0) {
- offset = p - begin;
+ offset = p - begin + 1;
}
*remain -= offset;
*pos += offset;
}
else {
GET16 (elt->mx.priority);
+ datalen -= sizeof (guint16);
if (! dns_parse_labels (in, &elt->mx.name, &p, rep, remain, TRUE)) {
msg_info ("invalid labels in MX record");
return -1;
static void
spf_record_dns_callback (struct rspamd_dns_reply *reply, gpointer arg)
{
- struct spf_dns_cb *cb = arg;
+ struct spf_dns_cb *cb = arg;
gchar *begin;
- union rspamd_reply_element *elt_data;
- GList *tmp = NULL, *tmp1, *elt, *last;
- struct worker_task *task;
+ union rspamd_reply_element *elt_data;
+ GList *tmp = NULL, *tmp1,
+ *elt, *last;
+ struct worker_task *task;
+ struct spf_addr *new_addr;
task = cb->rec->task;
}
}
else if (reply->type == DNS_REQUEST_A) {
- /* XXX: process only one record */
- cb->addr->addr = ntohl (elt_data->a.addr[0].s_addr);
+ if (cb->addr->addr == 0) {
+ cb->addr->addr = ntohl (elt_data->a.addr[0].s_addr);
+ }
+ else {
+ /* Insert one more address */
+ tmp = g_list_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->addr = ntohl (elt_data->a.addr[0].s_addr);
+ cb->rec->addrs = g_list_insert_before (cb->rec->addrs, tmp, new_addr);
+ }
+ else {
+ msg_info ("wrong address list");
+ }
+ }
+
}
break;
case SPF_RESOLVE_A:
cb = memory_pool_alloc (task->task_pool, sizeof (struct spf_dns_cb));
cb->rec = rec;
cb->addr = addr;
+ addr->addr = 0;
cb->cur_action = SPF_RESOLVE_MX;
cb->in_include = rec->in_include;
if (make_dns_request (task->resolver, task->s, task->task_pool, spf_record_dns_callback, (void *)cb, DNS_REQUEST_MX, host)) {