Socket...ddrInfo(3pm)
πΈ NAME πΈ
okay so this page is Socket...ddrInfo(3pm) from the User Contributed Perl Documentation set (yeah the header literally truncates the name, iykyk π), and the module it's all about is Socket::GetAddrInfo β address-family independent name resolving functions β¨
that's the whole vibe bestie. resolving names. no matter what address family you're in. slay π
π SYNOPSIS π
use Socket qw( SOCK_STREAM );
use Socket::GetAddrInfo qw( getaddrinfo getnameinfo );
use IO::Socket;
my %hints = ( socktype => SOCK_STREAM );
my ( $err, @res ) = getaddrinfo( "www.google.com", "www", \%hints );
die "Cannot resolve name - $err" if $err;
my $sock;
foreach my $ai ( @res ) {
my $candidate = IO::Socket->new();
$candidate->socket( $ai->{family}, $ai->{socktype}, $ai->{protocol} )
or next;
$candidate->connect( $ai->{addr} )
or next;
$sock = $candidate;
last;
}
if( $sock ) {
my ( $err, $host, $service ) = getnameinfo( $sock->peername );
print "Connected to $host:$service\n" if !$err;
}
like, that's the whole plot. you ask for addresses, you try them one by one, you connect, and then you turn the connected address back into a cute lil host:service pair. periodt. π¦
π DESCRIPTION π
so the RFC 2553 functions getaddrinfo and getnameinfo give you a whole abstracted way to convert between a pair of host name/service name and socket addresses, or the other way around. getaddrinfo converts names into a set of arguments you then pass to the socket() and connect() syscalls, and getnameinfo converts a socket address back into its host name/service name pair. it's giving bidirectional glow-up π
these functions are a genuinely useful interface for doing either of those name resolution operations, without you having to deal with IPv4/IPv6 transparency, or whether the underlying host can support IPv6 at all, or any of those other such issues. however β and this is the messy part β not all platforms can support the underlying calls at the C layer, which means a whole dilema for authors wishing to write forward-compatible code. either you support these functions and cause the code not to work on older platforms, or you stick to the older "legacy" resolvers such as gethostbyname(), which means the code becomes more portable. it's giving "pick your struggle" π
this module attempts to solve this problem by detecting at compiletime whether the underlying OS will support these functions. if it does not, the module will use pure-perl emulations of the functions using the legacy resolver functions instead. the emulations support the same interface as the real functions, and behave as close as is resonably possible to emulate using the legacy resolvers. see Socket::GetAddrInfo::Emul for the details on the limits of this emulation β it's not magic, bestie, it's a fallback. π«Ά
as of Perl version 5.14.0, Perl already supports getaddrinfo in core. on such a system, this module simply uses the functions provided by Socket, and does not need to use its own compiled XS, or pure-perl legacy emulation. iconic behavior honestly. π
and since Socket in core now provides all the functions also provided by this module, it is likely this may be the last released version of this module. and code currently using this module would be advised to switch to using core Socket instead. so likeβ¦ no cap, if you're still on this, it's giving vintage π
β¨ EXPORT TAGS β¨
the following tags may be imported by use Socket::GetAddrInfo qw( :tag ):
AIβ imports all of theAI_*constants forgetaddrinfoflagsNIβ imports all of theNI_*constants forgetnameinfoflagsEAIβ imports all of theEAI_*for error valuesconstantsβ imports all of the above constants
so basically pick your favorite or just take the whole bundle, no judgment π
π₯ FUNCTIONS π₯
π ( $err, @res ) = getaddrinfo( $host, $service, $hints )
getaddrinfo turns human-readable text strings (containing hostnames, numeric addresses, service names, or port numbers) into sets of binary values containing socket-level representations of these addresses. so like, words go in, binary socket addresses come out. the glow-up is real β¨
when given both host and service, this function attempts to resolve the host name to a set of network addresses, and the service name into a protocol and port number, and then returns a list of address structures suitable to connect() to it.
when given just a host name, this function attempts to resolve it to a set of network addresses, and then returns a list of these addresses in the returned structures.
when given just a service name, this function attempts to resolve it to a protocol and port number, and then returns a list of address structures that represent it suitable to bind() to.
when given neither name, it generates an error. like, bestie, you have to give me something π
the optional $hints parameter can be passed a HASH reference to indicate how the results are generated. it may contain any of the following four fields:
flags => INTβ a bitfield containingAI_*constants. at least the following flags will be available:AI_PASSIVEβ indicates that this resolution is for a localbind()for a passive (i.e. listening) socket, rather than an active (i.e. connecting) socket.AI_CANONNAMEβ indicates that the caller wishes the canonical hostname (canonname) field of the result to be filled in.AI_NUMERICHOSTβ indicates that the caller will pass a numeric address, rather than a hostname, and thatgetaddrinfomust not perform a resolve operation on this name. this flag will prevent a possibly-slow network lookup operation, and instead return an error, if a hostname is passed. so it's the "don't you dare do a network call" flag, lowkey iconic π- other flags may be provided by the OS.
family => INTβ restrict to only generating addresses in this address familysocktype => INTβ restrict to only generating addresses of this socket typeprotocol => INTβ restrict to only generating addresses for this protocol
errors are indicated by the $err value returned; which will be non-zero in numeric context, and contain a string error message as a string. the value can be compared against any of the EAI_* constants to determine what the error is. rather than explicitly checking, see also Socket::GetAddrInfo::Strict which provides functions that throw exceptions on errors. π
if no error occurs, @res will contain HASH references, each representing one address. it will contain the following five fields:
family => INTβ the address family (e.g.AF_INET)socktype => INTβ the socket type (e.g.SOCK_STREAM)protocol => INTβ the protocol (e.g.IPPROTO_TCP)addr => STRINGβ the address in a packed string (such as would be returned bypack_sockaddr_in)canonname => STRINGβ the canonical name for the host if theAI_CANONNAMEflag was provided, orundefotherwise. this field will only be present on the first returned address. so don't go looking for it on all of them, it's a first-born situation π
π ( $err, $host, $service ) = getnameinfo( $addr, $flags, $xflags )
getnameinfo turns a binary socket address into a pair of human-readable strings, containing the host name, numeric address, service name, or port number. it's the reverse glow-up of getaddrinfo β binary in, cute readable strings out π¦
the optional $flags parameter is a bitfield containing NI_* constants. at least the following flags will be available:
NI_NUMERICHOSTβ requests that a human-readable string representation of the numeric address is returned directly, rather than performing a name resolve operation that may convert it into a hostname.NI_NUMERICSERVβ requests that the port number be returned directly as a number representation rather than performing a name resolve operation that may convert it into a service name.NI_NAMEREQDβ if a name resolve operation fails to provide a name, then this flag will causegetnameinfoto indicate an error, rather than returning the numeric representation as a human-readable string. it's giving "name or nothing" π€NI_DGRAMβ indicates that the socket address relates to aSOCK_DGRAMsocket, for the services whose name differs betweenTCPandUDPprotocols.- other flags may be provided by the OS.
the optional $xflags parameter is a bitfield containing NIx_* constants. these are a Perl-level extension to the API, to indicate extra information. special little bonus features, we love to see it β¨
NIx_NOHOSTβ indicates that the caller is not interested in the hostname of the result, so it does not have to be converted;undefwill be returned as the hostname.NIx_NOSERVβ indicates that the caller is not interested in the service name of the result, so it does not have to be converted;undefwill be returned as the service name.
errors are indicated by the $err value returned; which will be non-zero in numeric context, and contain a string error message as a string. the value can be compared against any of the EAI_* constants to determine what the error is. rather than explicitly checking, see also Socket::GetAddrInfo::Strict which provides functions that throw exceptions on errors. π
β¨ EXAMPLES β¨
π Lookup for "connect"
The getaddrinfo function converts a hostname and a service name into a list of structures, each containing a potential way to connect() to the named service on the named host. It's giving matchmaking, honestly π
my %hints = ( socktype => SOCK_STREAM );
my ( $err, @res ) = getaddrinfo( $hostname, $servicename, \%hints );
die "Cannot getaddrinfo - $err" if $err;
my $sock;
foreach my $ai ( @res ) {
my $candidate = IO::Socket->new();
$candidate->socket( $ai->{family}, $ai->{socktype}, $ai->{protocol} )
or next;
$candidate->connect( $ai->{addr} )
or next;
$sock = $candidate;
last;
}
Because a list of potential candidates is returned, the while loop tries each one in turn until it finds one that succeeds both the socket() and connect() calls. Basically speed-dating for sockets, and bestie, only the one that passes both vibe checks gets to stay π«Ά
This function performs the work of the legacy functions gethostbyname, getservbyname, inet_aton and pack_sockaddr_in.
π Making a human-readable string out of an address
The getnameinfo function converts a socket address, such as returned by getsockname or getpeername, into a pair of human-readable strings representing the address and service name. Translating robot-speak into people-speak, iconic behaviour β¨
my ( $err, $hostname, $servicename ) = getnameinfo( $socket->peername );
die "Cannot getnameinfo - $err" if $err;
print "The peer is connected from $hostname\n";
Since in this example only the hostname was used, the redundant conversion of the port number into a service name may be omitted by passing the NIx_NOSERV flag. No cap, why do extra work when you don't have to π
my ( $err, $hostname ) = getnameinfo( $socket->peername, 0, NIx_NOSERV );
This function performs the work of the legacy functions unpack_sockaddr_in, inet_ntoa, gethostbyaddr and getservbyport.
π Resolving hostnames into IP addresses
To turn a hostname into a human-readable plain IP address, use getaddrinfo to turn the hostname into a list of socket structures, then getnameinfo on each one to make it a readable IP address again. Two-step glow-up π
my ( $err, @res ) = getaddrinfo( $hostname, "", { socktype => SOCK_RAW } );
die "Cannot getaddrinfo - $err" if $err;
while( my $ai = shift @res ) {
my ( $err, $ipaddr ) = getnameinfo( $ai->{addr}, NI_NUMERICHOST, NIx_NOSERV );
die "Cannot getnameinfo - $err" if $err;
print "$ipaddr\n";
}
The socktype hint to getaddrinfo filters the results to only include one socket type and protocol. Without this, most OSes return three combinations β for SOCK_STREAM, SOCK_DGRAM and SOCK_RAW β resulting in triplicate output of addresses. Not the triple-text energy we're going for, bestie π The NI_NUMERICHOST flag to getnameinfo causes it to return a string-formatted plain IP address, rather than reverse resolving it back into a hostname.
This combination performs the work of the legacy functions gethostbyname and inet_ntoa.
π οΈ BUILDING WITHOUT XS CODE
In some environments it may be preferred not to build the XS implementation, leaving a choice only of the core or pure-perl emulation implementations. Sometimes you just want the low-key version, and that's valid πΈ
$ perl Build.PL --pp
or
$ PERL_SOCKET_GETADDRINFO_NO_BUILD_XS=1 perl Build.PL
π BUGS
- Appears to FAIL on older Darwin machines (e.g.
osvers=8.11.1). The failure mode occurs int/02getnameinfo.tand appears to relate to an endian bug; expecting to receive 80 and instead receiving 20480 (which is a 16-bit 80 byte-swapped).
Okay so this one is genuinely cursed π an endian bug just flipping your numbers around for no reason. If you're on an old Darwin machine, just know it's not you, it's the bytes.
π SEE ALSO
- <http://tools.ietf.org/html/rfc2553> β Basic Socket Interface Extensions for IPv6
π«Ά ACKNOWLEDGEMENTS
Christian Hansen <chansen@cpan.org> β for help with some XS features and Win32 build fixes.
Zefram <zefram@fysh.org> β for help with fixing some bugs in the XS code.
Reini Urban <rurban@cpan.org> β for help with older perls and more Win32 build fixes.
π
AUTHOR
Paul Evans <leonerd@leonerd.org.uk>
and that's the whole page, bestie π you read every last bit, which is honestly main character energy. go forth and resolve some addresses, you absolute icon π
this was perl v5.40.0, dated 2025-02-01 β the Socket...ddrInfo(3pm) page from the User Contributed Perl Documentation, and yes that truncated title is just how it's spelled, no notes π
mwah, go slay πβ¨
π¦ where this page comes from
- debian trixie: libsocket-getaddrinfo-perl 0.22-6 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu resolute: libsocket-getaddrinfo-perl 0.22-6 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu stonking: libsocket-getaddrinfo-perl 0.22-6 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms