#!/usr/bin/perl package Pos::Webtop::Dns; use strict; use Pos::db; use Net::DNS::Resolver; =head1 NAME Pos::Webtop::DNS -- DNS resolution per-company webserver with fallback support. =head1 SYNOPSIS my $dottedQuadIp = Pos::Webtop::Dns::posdnsResolveHost( db => $db, companyId => 16, host => 'www.yahoo.com'); =cut sub posdnsResolveHost { my ($host, $resolver, $tb) = @{{@_}}{qw/host resolver toolBox/}; my $addr = undef; my $clean = 0; my $ip = undef; my $supernattedIp = undef; my $db = $tb->getWebtopDbWriter(); my $client = $tb->getClient(); my $webSessionId = $client->getSessionId(); my $companyId = $client->getCustomerId(); if (not defined($resolver)) { $resolver = Net::DNS::Resolver->new or return undef; my @nameservers = $db->query(sql => " select RAWIP32_TO_DOTTED_QUAD_NO(dns_server_act_address) from customer_dns_servers where customer_id = '" . $db->escape(dirty => $companyId) . "' "); if (scalar(@nameservers) == 0) { return undef; } $ip = $nameservers[0]; # acquire a supernat for this ip... # if we have a web session, make it a web session nat, else, backend dynamic... if ( defined($webSessionId) ) { $supernattedIp = $tb->getSupernattedIp( host=> $ip ); } else { $supernattedIp = $tb->getSupernatInternalAddress( webSessionNat=> 0, ip=> $nameservers[0] ); } if ( not defined $supernattedIp ) { $client->logger( severity=>'WARNING', logMessage=>'WEBTOP Dns: Supernat failed!' ); return undef; } if ( $supernattedIp =~ /^((?:\d+\.){3}\d+)$/ ) { $supernattedIp = $1; } else { warn "Pos::Webtop::Dns::posdnsResolveHost(): Got invalid ip from supernat request: '$supernattedIp'; returning undef"; return undef; } $resolver->{'nameservers'} = [ $supernattedIp ]; } else { $clean = 1; } my $response = $resolver->query($host); if ( defined($supernattedIp) && !defined($webSessionId) ) { # must free backend dynamic nat Pos::Webtop::Supernat::supernatReleaseDynamicBackendNat( db=> $db, companyId=> $companyId, actualAddress=> $ip ); } if ( defined($response) ) { foreach my $answer ($response->answer) { if ($answer->{"class"} ne 'IN') { next; } if ($answer->{"type"} ne 'A') { next; } $addr = $answer->rdatastr; } } if (($clean == 0) and not defined($addr)) { # try one more time with global dns $addr = Pos::Webtop::Dns::posdnsResolveHost(toolBox => $tb, host => $host, resolver => Net::DNS::Resolver->new); } return $addr; } 1;