Hey,
IPv6 is probably of little to no concern to most people, but I've seen at
least one domains I can't accept mail from because of IPv6.
nl.linux.org has 2 IPv6 MXs, and that makes require_resolvable_fromhost barf.
So, I made the attached modifications.
I borrowed the has_ipv6 stuff from Net::DNS::Resolver::Base.pm, when IPv6
support is added to qpsmtpd (yes, when :P) that should move somewhere global.
Ages ago I did briefly look into adding full IPv6 support, but fell over due
to a general lack of perl knowledge, and failling to find a nice method to
fall back on IPv4, with that stuff from DNS::Resolver I might start to look
at it again soon.
I thought about just doing an ANY search, but in mx_valid that fails if a host
has a CNAME in their MX, and the CEOs personal email account provider do, so
I had to make it work another way.
One thing I have left out, is is_valid.
Currently it'll spit out a couple of these on IPv6 IPs:
"Use of uninitialized value in bitwise and (&)
at ./plugins/require_resolvable_fromhost line 104."
I have no idea how is_valid works, so haven't touched it :)
--
Mike Williams
--- require_resolvable_fromhost.orig 2006-08-21 11:53:21.000000000 +0100
+++ require_resolvable_fromhost 2006-08-21 11:55:18.000000000 +0100
@@ -3,6 +3,18 @@
use Socket;
my %invalid = ();
+my $has_ipv6;
+
+if (
+ eval {require Socket6;} &&
+ # INET6 prior to 2.01 will not work; sorry.
+ eval {require IO::Socket::INET6; IO::Socket::INET6->VERSION("2.00");}
+ ) {
+ import Socket6;
+ $has_ipv6=1;
+}else{
+ $has_ipv6=0;
+}
sub hook_mail {
my ($self, $transaction, $sender) = @_;
@@ -38,6 +50,7 @@
sub check_dns {
my ($self, $host) = @_;
+ my @host_answers;
# for stuff where we can't even parse a hostname out of the address
return 0 unless $host;
@@ -53,15 +66,24 @@
}
my $query = $res->search($host);
if ($query) {
- foreach my $rr ($query->answer) {
- if ($rr->type eq "A") {
- return is_valid($rr->address);
- }
- elsif ($rr->type eq "MX") {
- return mx_valid($self, $rr->exchange, $host);
+ foreach my $rrA ($query->answer) {
+ push(@host_answers, $rrA);
+ }
+ }
+ if($has_ipv6){
+ my $query = $res->search($host, 'AAAA');
+ if ($query) {
+ foreach my $rrAAAA ($query->answer) {
+ push(@host_answers, $rrAAAA);
}
}
}
+ if(@host_answers){
+ foreach my $rr (@host_answers) {
+ return is_valid($rr->address) if $rr->type eq "A" or $rr->type eq "AAAA";
+ return mx_valid($self, $rr->exchange, $host) if $rr->type eq "MX";
+ }
+ }
else {
$self->log(LOGWARN, "$$ query for $host failed: ", $res->errorstring)
unless $res->errorstring eq "NXDOMAIN";
@@ -88,10 +110,24 @@
sub mx_valid {
my ($self, $name, $host) = @_;
my $res = new Net::DNS::Resolver;
- my $query = $res->search($name);
+ my @mx_answers;
+ my $query = $res->search($name, 'A');
if ($query) {
- foreach my $rr ($query->answer) {
- next unless $rr->type eq "A";
+ foreach my $rrA ($query->answer) {
+ push(@mx_answers, $rrA);
+ }
+ }
+ if($has_ipv6){
+ my $query = $res->search($name, 'AAAA');
+ if ($query) {
+ foreach my $rrAAAA ($query->answer) {
+ push(@mx_answers, $rrAAAA);
+ }
+ }
+ }
+ if(@mx_answers){
+ foreach my $rr (@mx_answers) {
+ next unless $rr->type eq "A" or $rr->type eq "AAAA";
return is_valid($rr->address);
}
}