sjk has asked for the wisdom of the Perl Monks concerning the following question:

UPDATE:
OK, So I have at least figured out the cause of the problem after watching nslookup and my perl script communicate with the name server. What is happening is that the result of the lookup is to large to stick into a single UDP packet so when it sends it back to me, it is marked as truncated. nslookup sees this and redoes the query in TCP, which is why I am able to get 35 hosts.
--------------------------------

Perl appears to ignore the packet being marked as truncated and displays 34 addresses, which seems to be the maximum amount a UDP packet can hold. So, is there any way I can make gethostbyname() do the lookup in TCP rather then UDP I have been pulling my hair out all day today trying to figure out what is going on, and I am very confident that I have hit a bug or a limitation in my setup.

I am using v5.8.4 built for sun4-solaris-64int on Solaris 10. I have configured by dns server to do round robin with 35 www servers. Doing an nslookup on www will list 35 ip's, which is expected and eliminates the name server from this problem.

So, in perl I am attempting to grab all those IPs and stick them into an array and now matter which way I do it, it always returns on 34 hosts, leaving off one.

I have tried things like:
@addresses = gethostbyname("www"); @addresses = map { inet_ntoa($_) } @addresses[4 .. $#addresses];
and no matter what I do, the array is always missing one ip address. However, before you blame my code, I have a few other round robin entries (all with less then 10 hosts) and all the IPs from those hosts appear in the array. Is there a limitation to the size of the packet that gethostbyname can handle or something I am overlooking?

Anyone have any ideas?
$ perl -V Summary of my perl5 (revision 5 version 8 subversion 4) configuration: Platform: osname=solaris, osvers=2.10, archname=sun4-solaris-64int uname='sunos localhost 5.10 sun4u sparc SUNW,Ultra-2' config_args='' hint=recommended, useposix=true, d_sigaction=define usethreads=undef use5005threads=undef useithreads=undef usemultipl +icity=undef useperlio=define d_sfio=undef uselargefiles=define usesocks=undef use64bitint=define use64bitall=undef uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='cc', ccflags ='-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -xar +ch=v8 -D_TS_ERRNO', optimize='-xO3 -xspace -xildoff', cppflags='' ccversion='Sun WorkShop', gccversion='', gccosandvers='' intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=87654321 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=1 +6 ivtype='long long', ivsize=8, nvtype='double', nvsize=8, Off_t='of +f_t', lseeksize=8 alignbytes=8, prototype=define Linker and Libraries: ld='cc', ldflags ='' libpth=/lib /usr/lib /usr/ccs/lib libs=-lsocket -lnsl -ldl -lm -lc perllibs=-lsocket -lnsl -ldl -lm -lc libc=/lib/libc.so, so=so, useshrplib=true, libperl=libperl.so gnulibc_version='' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-R /usr/ +perl5/5.8.4/lib/sun4-solaris-64int/CORE' cccdlflags='-KPIC', lddlflags='-G' Characteristics of this binary (from libperl): Compile-time options: USE_64_BIT_INT USE_LARGE_FILES Locally applied patches: 22667 The optree builder was looping when constructing the ops + ... 22715 Upgrade to FileCache 1.04 22733 Missing copyright in the README. 22746 fix a coredump caused by rv2gv not fully converting a PV + ... 22755 Fix 29149 - another UTF8 cache bug hit by substr. 22774 [perl #28938] split could leave an array without ... 22775 [perl #29127] scalar delete of empty slice returned garb +age 22776 [perl #28986] perl -e "open m" crashes Perl 22777 add test for change #22776 ("open m" crashes Perl) 22778 add test for change #22746 ([perl #29102] Crash on assig +n ... 22781 [perl #29340] Bizarre copy of ARRAY make sure a pad op's + ... 22796 [perl #29346] Double warning for int(undef) and abs(unde +f) ... 22818 BOM-marked and (BOMless) UTF-16 scripts not working 22823 [perl #29581] glob() misses a lot of matches 22827 Smoke [5.9.2] 22818 FAIL(F) MSWin32 WinXP/.Net SP1 (x86/ +1 cpu) 22830 [perl #29637] Thread creation time is hypersensitive 22831 improve hashing algorithm for ptr tables in perl_clone: +... 22839 [perl #29790] Optimization busted: '@a = "b", sort @a' . +.. 22850 [PATCH] 'perl -v' fails if local_patches contains code s +nippets 22852 TEST needs to ignore SCM files 22886 Pod::Find should ignore SCM files and dirs 22888 Remove redundant %SIG assignments from FileCache 23006 [perl #30509] use encoding and "eq" cause memory leak 23074 Segfault using HTML::Entities 23106 Numeric comparison operators mustn't compare addresses o +f ... 23320 [perl #30066] Memory leak in nested shared data structur +es ... 23321 [perl #31459] Bug in read() Built under solaris Compiled at Jan 21 2005 15:27:47 @INC: /usr/perl5/5.8.4/lib/sun4-solaris-64int /usr/perl5/5.8.4/lib /usr/perl5/site_perl/5.8.4/sun4-solaris-64int /usr/perl5/site_perl/5.8.4 /usr/perl5/site_perl /usr/perl5/vendor_perl/5.8.4/sun4-solaris-64int /usr/perl5/vendor_perl/5.8.4 /usr/perl5/vendor_perl .

Janitored by holli - added readmore tags

Replies are listed 'Best First'.
Re: gethostbyname Problem on solaris 10
by mugwumpjism (Hermit) on May 26, 2005 at 02:29 UTC

    You might find that there is a limit of 16 or 32 addresses per query somewhere.

    To work around this problem, each time you call gethostbyname, it should return the list of addresses in a different order.

    For this reason, commonly nameservers are configured to only return 3 addresses at a time with large round robins like this.

    Also, whenever I am experiencing name services weirdness, the very first thing I do is curse loudly at and garott the Name Services Cache Daemon (ncsd).

    $h=$ENV{HOME};my@q=split/\n\n/,`cat $h/.quotes`;$s="$h/." ."signature";$t=`cat $s`;print$t,"\n",$q[rand($#q)],"\n";
Re: gethostbyname Problem on solaris 10
by mikeraz (Friar) on May 26, 2005 at 13:10 UTC

    So what happens when you implement a dead simple test case like:

    #!/usr/bin/perl # get host by name exploration # get me is the test hostname I set up to try this out it has 35 addre +sses assigned to it. ($name,$aliases,$addrtype,$length,@addrs) = gethostbyname "getme.patc +h.com"; # print "$name $aliases $addrtype $length\n"; foreach (@addrs) { ($a,$b,$c,$d) = unpack("C4",$_); print "$a.$b.$c.$d\n"; } # yep, most of the above is cut and paste from perlfunc manpage

    ??