Catching DNS errors

Andre Nathan <[email protected]> Thu, 21 Jun 2012 12:06:58 -0300
Newsgroups gmane.mail.spam.spf.devel
Message-ID <1340291218.12144.6.camel@andre>
Hello

Below is a simple C program using libspf2 to check the records for a
domain which is known not to have DNS problems:

$ host -t txt gwmail.bradescoseguros.com.br
;; connection timed out; no servers could be reached

When I call SPF_request_query_mailfrom(), I get an invalid result:

$ ./spf 
spf_compile.c:523    Debug: Parsing macro starting at Please%_see%
_http://www.openspf.org/Why?id=%{S}&ip=%{C}&receiver=%{R}
spf_compile.c:1210   Debug: Compiling record v=spf1 
spf_dns.c:54         Debug: DNS[cache] lookup:
gwmail.bradescoseguros.com.br SPF (99)
spf_dns.c:54         Debug: DNS[resolv] lookup:
gwmail.bradescoseguros.com.br SPF (99)
spf_dns_resolv.c:311 Debug: query failed: err = -1  Host name lookup
failure (2): gwmail.bradescoseguros.com.br
spf_dns.c:66         Debug: DNS[resolv] found record
spf_dns.c:69         Debug:     DOMAIN: gwmail.bradescoseguros.com.br
TYPE: SPF (99)
spf_dns.c:76         Debug:     TTL: 0  RR found: 0  herrno: 2  source:
resolv
spf_dns.c:66         Debug: DNS[cache] found record
spf_dns.c:69         Debug:     DOMAIN: gwmail.bradescoseguros.com.br
TYPE: SPF (99)
spf_dns.c:76         Debug:     TTL: 0  RR found: 0  herrno: 2  source:
resolv
spf_server.c:384     Debug: get_record(gwmail.bradescoseguros.com.br):
TRY_AGAIN
query error: DNS lookup failure
result is (invalid)
reason is (invalid)

Shouldn't the TRY_AGAIN DNS response result in a TEMPERROR?

The program is pasted below. I also include a Perl script that returns a
TEMPERROR result, which is what postfix-policyd-spf-perl also returns.

Am I doing something wrong here?

Best regards,
Andre

#include <err.h>
#include <stdio.h>

#include <netinet/in.h>

#include <spf2/spf.h>
#include <spf2/spf_server.h>
#include <spf2/spf_request.h>
#include <spf2/spf_response.h>
#include <spf2/spf_dns.h>
#include <spf2/spf_log.h>

int
main(void)
{
    SPF_errcode_t r;
    SPF_server_t *server;
    SPF_request_t *req;
    SPF_response_t *resp;

    server = SPF_server_new(SPF_DNS_CACHE, 1);
    if (server == NULL)
        err(1, NULL);

    req = SPF_request_new(server);
    if (req == NULL)
        err(1, NULL);

    r = SPF_request_set_ipv4_str(req, "189.57.226.93");
    if (r != 0)
        err(1, "%s", SPF_strerror(r));
    r = SPF_request_set_helo_dom(req, "gwmail.bradescoseguros.com.br");
    if (r != 0)
        err(1, "%s", SPF_strerror(r));

    r = SPF_request_query_mailfrom(req, &resp);
    if (r != 0)
        printf("query error: %s\n", SPF_strerror(r));

    printf("result is %s\n", SPF_strresult(SPF_response_result(resp)));
    printf("reason is %s\n", SPF_strresult(SPF_response_reason(resp)));

    return 0;
}

use Mail::SPF;

my $resolver = Net::DNS::Resolver->new(
    retrans         => 5,  # Net::DNS::Resolver default: 5
    retry           => 2,  # Net::DNS::Resolver default: 4
    # Makes for a total timeout for UDP queries of 5s * 2 = 10s.
);

my $spf_server = Mail::SPF::Server->new(
    dns_resolver    => $resolver,
    hostname => $MailName,
    query_rr_types  => Mail::SPF::Server->query_rr_type_txt,
    default_authority_explanation  =>
    'Please see http://www.openspf.net/Why?s=%{_scope};id=%{S};ip=
%{C};r=%{R}'
);

my $helo_request = eval {
  Mail::SPF::Request->new(
    scope      => 'helo',
    identity   => 'gwmail.bradescoseguros.com.br',
    ip_address => '189.57.226.93'
  );
};

if ($@) {
  my $err = $@;
  print "query error: $err\n";
  exit;
}

my $helo_result = $spf_server->process($helo_request);
my $code = $helo_result->code;
my $lexp = $helo_result->local_explanation;
print "result is $code\n";
if ($helo_result->is_code('fail')) {
  my $aexp = $helo_result->authority_explanation;
  print "local explanation: $lexp\n";
}