Classify host (an authority host, optionally bracketed and/or with a
:port suffix) and produce the numeric address to pin the connection to in
pinnedIp. This is the SINGLE address classifier all SSRF decisions flow
through:
- IP literals (IPv4 in every numeric encoding, IPv6 including embedded-IPv4,
ULA, link-local and loopback) are classified directly and pinnedIp is the
host verbatim (already a literal vibe will not re-resolve).
- localhost and ::1 are classified as loopback; pinnedIp is the host
verbatim.
- A registered hostname is resolved; EVERY returned A/AAAA address is
classified and pinnedIp is set to the first one. If ANY resolved address
is loopback/private/link-local the result is privateOrLinkLocal (resolved
loopback is demoted to private so it cannot claim the literal-loopback dev
allowance — DNS-rebinding guard). On a resolution error (or no usable
record) the result is privateOrLinkLocal with an empty pinnedIp (fail
CLOSED).
@safe (DNS resolution is @system in std.socket; wrapped here).
Classify host (an authority host, optionally bracketed and/or with a :port suffix) and produce the numeric address to pin the connection to in pinnedIp. This is the SINGLE address classifier all SSRF decisions flow through:
- IP literals (IPv4 in every numeric encoding, IPv6 including embedded-IPv4, ULA, link-local and loopback) are classified directly and pinnedIp is the host verbatim (already a literal vibe will not re-resolve). - localhost and ::1 are classified as loopback; pinnedIp is the host verbatim. - A registered hostname is resolved; EVERY returned A/AAAA address is classified and pinnedIp is set to the first one. If ANY resolved address is loopback/private/link-local the result is privateOrLinkLocal (resolved loopback is demoted to private so it cannot claim the literal-loopback dev allowance — DNS-rebinding guard). On a resolution error (or no usable record) the result is privateOrLinkLocal with an empty pinnedIp (fail CLOSED).
@safe (DNS resolution is @system in std.socket; wrapped here).