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

I've encountered a problem with some client-side socket code that's been working fine for many, many years on a variety of systems.

The basic problem appears to be the value of AF_INET as it's encoded into the connect() call. If I use the sockaddr_in() function from Socket.pm it works fine, but if I pack() the structure myself, using the AF_INET value from Socket.pm, it fails.

I'm not sure if this is a bug in Perl... or maybe OS X 10.5 Leopard... or perhaps I've simply been doing something wrong for many years. If this is not a bug in Perl and/or Leopard, then I'd appreciate some clarification.

Below is a test script that does both methods (sockaddr_in vs pack) and the results I see on Leopard. Incidently, because of historic reasons, I can't use sockaddr_in, therefore I need to use pack.

#!/usr/bin/perl use Socket; $addr = shift; $port = shift; die "Usage; $0 <ip address> <port number>\n" unless ($addr and $port); $proto = getprotobyname('tcp'); print "proto=[$proto]\n"; print "AF_INET=[", AF_INET, "]\n"; print "SOCK_STREAM=[", SOCK_STREAM, "]\n"; #******************************************************************* print "\nConnect using sockaddr_in method...\n"; $paddr = sockaddr_in($port, pack('C4', split('\.', $addr))); printf "paddr=[%d, %d, %d.%d.%d.%d]\n", unpack('S n C4', $paddr); socket(SOCK, AF_INET, SOCK_STREAM, $proto) || die "socket: $!\n"; connect(SOCK, $paddr) || die "connect: $!\n"; print "Connection to $addr:$port established\n"; close (SOCK) || die "close: $!"; #******************************************************************* print "\nConnect using pack method...\n"; $paddr = pack('S n C4 x8', AF_INET, $port, split('\.', $addr)); printf "paddr=[%d, %d, %d.%d.%d.%d]\n", unpack('S n C4', $paddr); socket(SOCK, AF_INET, SOCK_STREAM, $proto) || die "socket: $!\n"; connect(SOCK, $paddr) || die "connect: $!\n"; print "Connection to $addr:$port established\n"; close (SOCK) || die "close: $!\n"; exit;

I've run this test script on a variety of systems (Solaris, HP-UX, Redhat, RHEL, OS X 10.3/10.4) and both "connection methods" work fine... all EXCEPT for OS X 10.5/9A527 (aka Leopard). When I run the above test script on my MacBook Pro running OS X Leopard, I get the following results.

$ connect_test 127.0.0.1 22 proto=[6] AF_INET=[2] SOCK_STREAM=[1] Connect using sockaddr_in method... paddr=[512, 22, 127.0.0.1] Connection to 127.0.0.1:22 established Connect using pack method... paddr=[2, 22, 127.0.0.1] connect: Address family not supported by protocol family

My first thought, when I see the decoded value of $paddr after the sockaddr_in() call, is that AF_INET is supposed to be 512 on Leopard, but if that's true, why does AF_INET return 2?

Looking at /usr/include/sys/socket.h, where AF_INET is defined, the value is 2... the same thing AF_INET returns.

Also, looking in Socket.xs, in the pack_sockaddr_in() function, near the bottom, it sets sin.sin_family = AF_INET. So how is that sockaddr_in() eventually encodes 512? Am I decoding $paddr incorrectly?

I've tried this test on Leopard using the perl that comes with the OS (perl-5.8.8) and I've compiled 5.8.0, 5.8.6 and 5.8.8 myself (using "Configure -ds -e") and the results are the same.

Thanks for any clarification.

Replies are listed 'Best First'.
Re: Connect fails on OS X 10.5 (Leopard)
by merlyn (Sage) on Sep 13, 2007 at 23:04 UTC
    Since 10.5 is not yet released, aren't you violating an NDA by asking a question on other than the private mailing lists for 10.5 developers?
Re: Connect fails on OS X 10.5 (Leopard)
by Anonymous Monk on Feb 01, 2008 at 11:14 UTC
    The OS is official now, in fact I get the same issue (using the provided perl) in IO::Socket, the function getprotobyname('tcp') doesnt return any value