[erlang-questions] Inets and IPv6 (noob)

Kenji Rikitake <>
Fri May 1 06:07:42 CEST 2009


In the message <C61D2E52.10FB0%>
dated Tue, Apr 28, 2009 at 10:05:46PM -0700,
Michael Talyansky <> writes:
> On BSD, server was binding to (and listening on) IPv4 address. On Linux, it
> binds to IPv6 only (verified with netstat), unless I explicitly specify IPv4
> interface address in the bind_address tuple.

On Ubuntu 8.10 and 9.04, IPv6 is enabled as default.

See the following code from R13B; IPv6 takes precedence higher than
IPv4, if enabled.

%%% quoted from R13B lib/inets/src/http_server/httpd_util.erl
ip_address(Host) ->
    Inet = case gen_tcp:listen(0, [inet6]) of
               {ok, Dummyport} ->
                   gen_tcp:close(Dummyport),
                   inet6;
               _ ->
                   inet
           end,
    inet:getaddr(Host, Inet).
%%% unquote

> What should I set and where in order for the server to bind to both IPv4 and
> IPv6 addresses?

You should not do this, at least on FreeBSD (and other *BSDs), because
IPV6_V6ONLY is effective as default (see sysctl net.inet6.ip6.v6only).
(See also RFC3493 Section 5.3) In such an environment, you have to bind
separately to each of IPv4 and IPv6 addresses.

> I am using R13B, on BSD it was R13A. Could this be a factor?

I haven't checked out the R13A code, but on R12B5 the code was

%%% quoted from R12B5 lib/inets/src/http_server/httpd_util.erl
ip_address(Host) ->
    case (catch inet:getaddr(Host,inet6)) of
        {ok, {0, 0, 0, 0, 0, 16#ffff, _, _}} ->
            inet:getaddr(Host, inet);
        {ok, IPAddr} ->
            {ok, IPAddr};
        _ ->
            inet:getaddr(Host, inet)
    end.
%%% unquote

so the implementation might be changed.

(Note that {0, 0, 0, 0, 0, 16#ffff, _, _} represents the set of
IPv4-mapped address, which does not work on BSD and should be
deprecated.)

Kenji Rikitake



More information about the erlang-questions mailing list