 
 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 { } ;
 

    [ 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 )


M: inet6 parse-sockaddr
    >r dup sockaddr-in6-addr r> inet-ntop
    swap sockaddr-in6-port ntohs <inet6> ;

: addrspec-of-family ( af -- addrspec )
    {
