HttpUtils.pm: fixing memory leak in HttpUtils_gethostbyname (Forum #84372)

git-svn-id: https://svn.fhem.de/fhem/trunk@20375 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
rudolfkoenig
2019-10-17 22:52:43 +00:00
parent dfd7a090e0
commit a84dac05e5

View File

@@ -269,48 +269,57 @@ HttpUtils_gethostbyname($$$$)
return $fn->($hash, "Cant create UDP socket:$!", undef) if(!$c); return $fn->($hash, "Cant create UDP socket:$!", undef) if(!$c);
my %dh = ( conn=>$c, FD=>$c->fileno(), NAME=>"DNS", origHash=>$hash, my %dh = ( conn=>$c, FD=>$c->fileno(), NAME=>"DNS", origHash=>$hash,
addr=>$dnsServer, callback=>$fn ); addr=>$dnsServer, callback=>$fn, host=>$host, try6=>$try6 );
my %timerHash = ( hash=>\%dh, msg=>"DNS" );
my $bhost = join("", map { pack("CA*",length($_),$_) } split(/\./, $host)); my $bhost = join("", map { pack("CA*",length($_),$_) } split(/\./, $host));
my $qry = pack("nnnnnn", 0x7072,0x0100,1,0,0,0) . $dh{qry} = pack("nnnnnn", 0x7072,0x0100,1,0,0,0) .
$bhost . pack("Cnn", 0,$try6 ? 28:1,1); $bhost . pack("Cnn", 0,$try6 ? 28:1,1);
my $ql = length($qry); $dh{ql} = length($dh{qry});
Log 5, "DNS QUERY ".unpack("H*", $qry); Log 5, "DNS QUERY ".unpack("H*", $dh{qry});
sub
directReadFn($) { # Parse the answer
my ($dh) = @_;
RemoveInternalTimer($dh);
$dh{directReadFn} = sub() { # Parse the answer
RemoveInternalTimer(\%timerHash);
my $buf; my $buf;
my $len = sysread($dh{conn},$buf,65536); my $len = sysread($dh->{conn},$buf,65536);
HttpUtils_Close(\%dh); HttpUtils_Close($dh);
Log 5, "DNS ANSWER ".($len?$len:0).":".($buf ? unpack("H*", $buf):"N/A"); Log 5, "DNS ANSWER ".($len?$len:0).":".($buf ? unpack("H*", $buf):"N/A");
my ($err, $addr, $ttl) = HttpUtils_dnsParse($buf,$ql,$try6); my ($err, $addr, $ttl) = HttpUtils_dnsParse($buf, $dh->{ql}, $dh->{try6});
return HttpUtils_gethostbyname($hash, $host, 0, $fn) if($err && $try6); return HttpUtils_gethostbyname($dh->{origHash},
return $fn->($hash, "DNS: $err", undef) if($err); $dh->{host}, 0, $dh->{callback})
Log 4, "DNS result for $host: ".ip2str($addr).", ttl:$ttl"; if($err && $dh->{try6});
$HU_dnsCache{$host}{TS} = gettimeofday(); return $dh->{callback}->($dh->{origHash}, "DNS: $err", undef) if($err);
$HU_dnsCache{$host}{TTL} = $ttl; Log 4, "DNS result for $dh->{host}: ".ip2str($addr).", ttl:$ttl";
$HU_dnsCache{$host}{addr} = $addr; $HU_dnsCache{$dh->{host}}{TS} = gettimeofday();
return $fn->($hash, undef, $addr); $HU_dnsCache{$dh->{host}}{TTL} = $ttl;
}; $HU_dnsCache{$dh->{host}}{addr} = $addr;
return $dh->{callback}->($dh->{origHash}, undef, $addr);
}
$dh{directReadFn} = \&directReadFn;
$selectlist{\%dh} = \%dh; $selectlist{\%dh} = \%dh;
my $dnsQuery; $dh{dnsTo} = 0.25;
my $dnsTo = 0.25; $dh{lSelectTs} = $selectTimestamp;
my $lSelectTs = $selectTimestamp; $dh{selectTimestamp} = $selectTimestamp;
$dnsQuery = sub()
sub
dnsQuery($)
{ {
$dnsTo *= 2 if($lSelectTs != $selectTimestamp); my ($dh) = @_;
$lSelectTs = $selectTimestamp; $dh->{dnsTo} *= 2 if($dh->{lSelectTs} != $dh->{selectTimestamp});
return HttpUtils_Err(\%timerHash) if($dnsTo > $hash->{timeout}/2); $dh->{lSelectTs} = $dh->{selectTimestamp};
my $ret = syswrite $dh{conn}, $qry; return HttpUtils_Err({ hash=>$dh, msg=>"DNS"})
if(!$ret || $ret != $ql) { if($dh->{dnsTo} > $dh->{origHash}->{timeout}/2);
my $ret = syswrite $dh->{conn}, $dh->{qry};
if(!$ret || $ret != $dh->{ql}) {
my $err = $!; my $err = $!;
HttpUtils_Close(\%dh); HttpUtils_Close($dh);
return $fn->($hash, "DNS write error: $err", undef); return $dh->{callback}->($dh->{origHash}, "DNS write error: $err", undef);
} }
InternalTimer(gettimeofday()+$dnsTo, $dnsQuery, \%timerHash); InternalTimer(gettimeofday()+$dh->{dnsTo}, \&dnsQuery, $dh);
}; }
$dnsQuery->(); dnsQuery(\%dh);
} }