views:

51

answers:

0

Hi!

I’m porting some software that I wrote for a White Russian OpenWRT system to a new Kamikaze 8.09.1 OpenWRT system but I am having some serious issues that I’m hoping you can help me with.

Old system
Linux kernel 2.4.34
MIPSEL arch
Perl 5.8.7
Net::DNS 0.48
IO 1.21
IO::Socket 1.28
IO::Socket::INET 1.28

New system
Linux kernel 2.6.26.8
MIPS arch
Perl 5.10.0
Net::DNS 0.66
IO 1.23_01
IO::Socket 1.30_01
IO::Socket::INET 1.31

First, let me provide some background information…

I am trying to resolve my server (clearprobe.winbeam.com) from within my Perl program and see the following if I enable debugging in Net::DNS:

resolve: Server 'clearprobe-ddns.winbeam.com'
;; query(clearprobe-ddns.winbeam.com)
;; setting up an AF_INET() family type UDP socket
;; send_udp(192.168.88.1:53)
;; send_udp(4.2.2.2:53)
;; send_udp(192.168.88.1:53)
;; send_udp(4.2.2.2:53)
resolve: res->errorstring: query timed out

Both of these servers resolve clearprobe.winbeam.com fine from the command line:

root@cwb-2-11:~# echo “nameserver 192.168.88.1” > /etc/resolv.conf
root@cwb-2-11:~# nslookup clearprobe-ddns.winbeam.com
Server:    192.168.88.1
Address 1: 192.168.88.1 router

Name:      clearprobe-ddns.winbeam.com
Address 1: 64.13.48.40 64-13-48-40.war.clearwire-dns.net

root@cwb-2-11:~# echo “nameserver 4.2.2.2” > /etc/resolv.conf
root@cwb-2-11:~# nslookup clearprobe-ddns.winbeam.com
Server:    4.2.2.2
Address 1: 4.2.2.2 vnsc-bak.sys.gtei.net

Name:      clearprobe-ddns.winbeam.com
Address 1: 64.13.48.40 64-13-48-40.war.clearwire-dns.net

Using Perl’s call to the C gethostbyaddr() function works fine, but I need to do another lookup later in the software which requires that I specify the nameserver (clearprobe-ddns.winbeam.com is the authority for my internal DNS zone), hence my Net::DNS requirement.

Now, here is the IO module-specific information:

What I am seeing is that the reply is coming back from the nameserver (confirmed via tcpdump – I can send the captures if you’d like), but the UDP packets are sitting in the process’s UDP receive queue pending reception by Net::DNS (the approx 1752 bytes per response stay queued waiting for $sel->can_read()):

root@cwb-2-11:~# netstat -una
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
udp     1752      0 0.0.0.0:52680           0.0.0.0:*
root@cwb-2-11:~# netstat -una
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
udp     5256      0 0.0.0.0:52680           0.0.0.0:*

If I force $sock[AF_INET]->recv($buf, $self->_packetsz) around line 803 of /usr/lib/perl5/5.10/Net/DNS/Resolver/Base.pm, instead of waiting for IO::Select’s can_read() function ( @ready = $sel->can_read($timeout)) to populate @ready, the response is received and processed.

Any idea what could be causing this issue?

In a possibly related matter, I noticed in another script that the following code fails in the same manner (network responses stay in the process’s TCP receive queue) with the new system:

$sock = new IO::Socket::INET(
PeerAddr => "$server",
PeerPort => 37,
Proto => 'tcp',
Timeout => 5
);

Whereas the following code works:

$sock = new IO::Socket::INET(
PeerAddr => "$server",
PeerPort => 37,
Proto => 'tcp'
);

I have looked through the NET::DNS code and don’t see a timeout passed for the UDP sockets, so I am not sure if that this is related or not.

Please let me know if I can provide you with any further information in order to help diagnose this issue.

Thanks!

-Rich