# IPv6-capable hostname lookup in ext/standard

- Thread: https://externals.io/message/133097
- Original archive: https://news-web.php.net/php.internals/133097
- Started by David CARLIER on 2026-11-13T17:44:35+00:00
- Messages: 3
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · RFCs at https://externals.io/rfc.md · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #133097 — David CARLIER — 2026-11-13T17:44:35+00:00

URL: https://externals.io/message/133097#133097

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()` and `gethostbynamel()` 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 with `socket_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:

1. Naming: a new function, or a new parameter on `gethostbynamel()`?
2. 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.

---

## #133098 — Xavier Leune — 2026-11-13T20:04:43+00:00

URL: https://externals.io/message/133097#133098 · In reply to: #133097

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()` and `gethostbynamel()` 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 with `socket_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:
>
> 1. Naming: a new function, or a new parameter on `gethostbynamel()`?
> 2. 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

---

## #133099 — David CARLIER — 2026-11-13T21:11:57+00:00

URL: https://externals.io/message/133097#133099 · In reply to: #133098

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.
