Hi !
GH-25446 asks for a way to resolve a hostname to IPv6 addresses.
ext/standard cannot do that through the system resolver today:
gethostbyname()andgethostbynamel()are IPv4-only by documentation.
Changing their return values would break callers expecting a dotted quad.- dns_get_record($host, DNS_AAAA) queries DNS directly and skips
/etc/hosts/nsswitch, so localhost and hosts-file entries do not resolve. socket_addrinfo_lookup()does it right but needs ext/sockets, and you
have to unpack its AddressInfo objects withsocket_addrinfo_explain().
I'd like to add a new function for master, something like:
function gethostaddresses(string $hostname, int $family = DNS_A |
DNS_AAAA): array|false {}
It returns the address strings in getaddrinfo() order, or false on failure.
It goes through the system resolver like stream connections do. $family
reuses DNS_A/DNS_AAAA, since the AF_* constants live in ext/sockets.
php_network_getaddresses() already wraps getaddrinfo(), so the change is
small and fits with the resolver cleanup in GH-15555.
Kind of open questions:
- Naming: a new function, or a new parameter on
gethostbynamel()? - Should $family take the DNS_* constants, or should ext/standard get its
own constants?
Unless there are objections, I'll open a PR in the coming days.
Cheers.
Hi David,
Le ven. 13 nov. 2026 à 18:46, David CARLIER devnexen@gmail.com a écrit :
Hi !
GH-25446 asks for a way to resolve a hostname to IPv6 addresses.
ext/standard cannot do that through the system resolver today:
gethostbyname()andgethostbynamel()are IPv4-only by documentation.
Changing their return values would break callers expecting a dotted quad.- dns_get_record($host, DNS_AAAA) queries DNS directly and skips
/etc/hosts/nsswitch, so localhost and hosts-file entries do not resolve.socket_addrinfo_lookup()does it right but needs ext/sockets, and you
have to unpack its AddressInfo objects withsocket_addrinfo_explain().I'd like to add a new function for master, something like:
function gethostaddresses(string $hostname, int $family =
DNS_A|
DNS_AAAA): array|false {}It returns the address strings in getaddrinfo() order, or false on
failure. It goes through the system resolver like stream connections do.
$family reuses DNS_A/DNS_AAAA, since the AF_* constants live in
ext/sockets. php_network_getaddresses() already wraps getaddrinfo(), so the
change is small and fits with the resolver cleanup in GH-15555.Kind of open questions:
- Naming: a new function, or a new parameter on
gethostbynamel()?- Should $family take the DNS_* constants, or should ext/standard get its
own constants?Unless there are objections, I'll open a PR in the coming days.
Cheers.
Great idea. A few questions:
- do you plan to return an empty array when there is no failure but no
matching record, or false ? - why only A and AAAA? Other records are useful too, especially SVC
- do you think you may wrap the syscall with a timeout somehow ? I’m not
sure it’s possible due to how the kernel handles it but it would be great - may you add the ip of the dns server to reach ?
With all that, the dns resolution would be much more useful on php.
Thanks,
Xavier
Hi Xavier,
Thanks for the feedback.
do you plan to return an empty array when there is no failure but no
matching record, or false ?
An empty array. false is only for when getaddrinfo() itself fails (e.g.
unknown host), with the usual warning like stream connections.
php_network_getaddresses() always queries AF_UNSPEC and $family is applied
afterwards, so it's easy to tell the two cases apart. Relying on
EAI_NODATA/EAI_ADDRFAMILY would not be portable anyway.
why only A and AAAA? Other records are useful too, especially SVC
getaddrinfo() only gives addresses back. SVCB/HTTPS, MX, TXT... are
DNS-only records, and /etc/hosts or nsswitch have no equivalent. They
belong in dns_get_record(), which does not know SVCB/HTTPS yet. That's a
a good suggestion !
do you think you may wrap the syscall with a timeout somehow ?
Not portably. getaddrinfo_a() is glibc only, and otherwise it means a
helper thread. Today the timeout comes from the resolver config
(resolv.conf timeout/attempts and so on), and stream connections behave
the same way since the connect timeout does not cover the name
resolution. I'd rather stay consistent with that.
may you add the ip of the dns server to reach ?
getaddrinfo() does not expose it. Depending on nsswitch, the answer can
come from /etc/hosts, nscd, systemd-resolved or mDNS, so there is not
always a DNS server to report. dns_get_record() is a better fit for that
kind of detail.
So I'll keep the proposal as is, and the PR will document and test the
empty array vs false behaviour.
Cheers.