"0.0.0.0" or
rot inet-pton *uint over set-sockaddr-in-addr ;
-<PRIVATE
-
-SYMBOL: port-override
-
-: (port) ( port -- port' ) port-override get swap or ;
-
-PRIVATE>
-
M: inet4 parse-sockaddr
>r dup sockaddr-in-addr <uint> r> inet-ntop
- swap sockaddr-in-port ntohs (port) <inet4> ;
+ swap sockaddr-in-port ntohs <inet4> ;
TUPLE: inet6 host port ;
M: inet6 parse-sockaddr
>r dup sockaddr-in6-addr r> inet-ntop
- swap sockaddr-in6-port ntohs (port) <inet6> ;
+ swap sockaddr-in6-port ntohs <inet6> ;
: addrspec-of-family ( af -- addrspec )
{
[ addrinfo>addrspec ] map
sift ;
-: prepare-resolve-host ( addrspec -- host' serv' flags )
- #! If the port is a number, we resolve for 'http' then
- #! change it later. This is a workaround for a FreeBSD
- #! getaddrinfo() limitation -- on Windows, Linux and Mac,
- #! we can convert a number to a string and pass that as the
- #! service name, but on FreeBSD this gives us an unknown
- #! service error.
- [ host>> ]
- [ port>> dup integer? [ port-override set "http" ] when ] bi
- over 0 AI_PASSIVE ? ;
-
HOOK: addrinfo-error io-backend ( n -- )
GENERIC: resolve-host ( addrspec -- seq )
C: <inet> inet
+: resolve-passive-host ( -- addrspecs )
+ { T{ inet6 f "::" f } T{ inet4 f "0.0.0.0" f } } [ clone ] map ;
+
+: prepare-addrinfo ( -- addrinfo )
+ "addrinfo" <c-object>
+ PF_UNSPEC over set-addrinfo-family
+ IPPROTO_TCP over set-addrinfo-protocol ;
+
+: fill-in-ports ( addrspecs port -- addrspecs )
+ [ >>port ] curry map ;
+
M: inet resolve-host
- [
- prepare-resolve-host
- "addrinfo" <c-object>
- [ set-addrinfo-flags ] keep
- PF_UNSPEC over set-addrinfo-family
- IPPROTO_TCP over set-addrinfo-protocol
- f <void*> [ getaddrinfo addrinfo-error ] keep *void*
- [ parse-addrinfo-list ] keep
- freeaddrinfo
- ] with-scope ;
+ [ port>> ] [ host>> ] bi [
+ f prepare-addrinfo f <void*>
+ [ getaddrinfo addrinfo-error ] keep *void*
+ [ parse-addrinfo-list ] keep freeaddrinfo
+ ] [ resolve-passive-host ] if*
+ swap fill-in-ports ;
M: f resolve-host drop { } ;