otp icon indicating copy to clipboard operation
otp copied to clipboard

Conf option to have an end to end ipv6 otp release

Open awetzel opened this issue 10 years ago • 24 comments

  • add support for ipv6 connections to Epmd
  • add a macro to define the default epmd ip: "::1" or "127.0.0.1"
  • add a macro to define the default proto_dist: inet_tcp or inet6_tcp
  • add a configure option to compile the whole otp in ipv6 default mode

The option --enable-epmd-ipv6 configure:

  • the -DEPMD6 CFLAG for epmd compilation
  • the default proto_dist (without init arg) to "inet6_tcp"
  • the epmd connection ip to "::1"

awetzel avatar Feb 04 '15 03:02 awetzel

The problem this pull request solves is when you want to run Erlang in a full IPV6 environment, with ipv6 nodes communicating through ipv6 sockets with EPMD :

  • currently Epmd did not support local connections (registration,query) through ipv6, fix that
  • default Epmd connection ip is hard coded : 127.0.0.1, make it "::1" or "127.0.0.1" depending on a macro : EPMD_IPV6
  • default proto_dist is inet_tcp, but when connecting to epmd though "::1", it has to be inet6_tcp, so make the default depending on the same macro EPMD_IPV6. It is necessary to change the default dist instead of using the flag -proto_dist because the default has to work and the previous modification would break if an ipv6 compatible proto_dist is not set.
  • add a convenient "configure" option : --enable-epmd-ipv6 to set the CFLAG -DEPMD6 for epmd compilation and the erlang flag -DEPMD_IPV6

I am using this patch in production since Erlang R14 : running some of my company erlang applications and many riak nodes in an ipv6 only environment and it works well.

So I though maybe this option can be useful to other users.

awetzel avatar Feb 04 '15 04:02 awetzel

Patch has passed first testings and has been assigned to be reviewed


I am a script, I am not human


OTP-Maintainer avatar Feb 04 '15 20:02 OTP-Maintainer

Patch has passed first testings and has been assigned to be reviewed


I am a script, I am not human


OTP-Maintainer avatar Apr 08 '15 01:04 OTP-Maintainer

I ping you again about this since I continue to need this change, do you think there is an issue with this request ?

awetzel avatar Apr 12 '15 02:04 awetzel

We will consider this patch for 18.1

IngelaAndin avatar Jun 10 '15 21:06 IngelaAndin

18.1 has been released and still no ipv6 :)

Do you have any idea if there is any problem in this PR / feature ? Do you plan to propose this feature otherwise ?

awetzel avatar Oct 15 '15 15:10 awetzel

There are several related PR/patches in this area. We are working on evaluating them, and we passed an IPV6 patch related to the distribution just recently. At the moment we have asked if this patch could be rebased and if so we think that yours need to be rebased upon it afterwards. https://github.com/erlang/otp/compare/maint...msantos:epmd-IPv6-node-reg

IngelaAndin avatar Oct 16 '15 13:10 IngelaAndin

Patch has passed first testings and has been assigned to be reviewed


I am a script, I am not human


OTP-Maintainer avatar Jan 12 '16 19:01 OTP-Maintainer

PR 864 is now on its way to be accepted, and then we hopefully can get somewhere with this PR and PR 708.

IngelaAndin avatar Feb 16 '16 15:02 IngelaAndin

Very good news, thank you for the update. Ipv6 is critical in our use. If you need feedback of using it with otp, I am available.(many production apps in my company using full ipv6 erlang with this patch)

awetzel avatar Feb 16 '16 21:02 awetzel

I have now merged PR 864, should be visible soon at github. When it is please consider the consequences for this PR and maybe rebase it.

Also the following diff that is now being tested and hopefully merged tomorrow as an improvment to the original PR 864.

diff --git a/erts/epmd/src/epmd_srv.c b/erts/epmd/src/epmd_srv.c
index 55ec0f7..e1bac99 100644
--- a/erts/epmd/src/epmd_srv.c
+++ b/erts/epmd/src/epmd_srv.c
@@ -380,7 +380,7 @@ void run(EpmdVars *g)
              epmd_cleanup_exit(g,1);
      }
    }
-      g->listenfd[i] = listensock[i];
+      g->listenfd[bound++] = listensock[i];

 #if HAVE_DECL_IPV6_V6ONLY
       opt = 1;
@@ -439,8 +439,6 @@ void run(EpmdVars *g)
        }
    }

-      bound++;
-
       if(listen(listensock[i], SOMAXCONN) < 0) {
           dbg_perror(g,"failed to listen on socket");
           epmd_cleanup_exit(g,1);
@@ -451,6 +449,7 @@ void run(EpmdVars *g)
       dbg_perror(g,"unable to bind any address");
       epmd_cleanup_exit(g,1);
   }
+  num_sockets = bound;
 #ifdef HAVE_SYSTEMD_DAEMON
     }
     sd_notifyf(0, "READY=1\n"
@@ -495,8 +494,8 @@ void run(EpmdVars *g)
    }

    for (i = 0; i < num_sockets; i++)
-     if (FD_ISSET(listensock[i],&read_mask)) {
-       if (do_accept(g, listensock[i]) && g->active_conn < g->max_conn) {
+     if (FD_ISSET(g->listenfd[i],&read_mask)) {
+       if (do_accept(g, g->listenfd[i]) && g->active_conn < g->max_conn) {
          /*
           * The accept() succeeded, and we have at least one file
           * descriptor still free, which means that another accept()

IngelaAndin avatar Mar 01 '16 14:03 IngelaAndin

OK actually the ipv6 registration part has collisions between the two PR, I am looking into it

awetzel avatar Mar 01 '16 23:03 awetzel

OK currently I am not seeing it on github, neither in maint , maint-18, master... please tell me if I am wrong be it seems that the commit is not currently visible. I will look for it again tomorrow

awetzel avatar Mar 02 '16 00:03 awetzel

It should be here now.

proxyles avatar Mar 02 '16 08:03 proxyles

OK actually the PR 864 covers exactly the same feature exactly the same way (except with an added check of EPMD6 and a welcomed refactoring which is better in PR864) in erts/epmd/src/epmd_srv.c, there are no added features in this file in my PR, so I removed all the changes of this PR in this file and rebased it.

So there will be no conflict, even with the diff you quoted.

awetzel avatar Mar 02 '16 09:03 awetzel

Thank you for the quick update. This change however is to late for 18.3 code freeze. Code that changes configure has an earlier freeze than other less sensitive code. Also there has come up some questions about if configure is the way to go or should it be solved by runtime options or environment variables instead. We will have to come back to this.

IngelaAndin avatar Mar 02 '16 13:03 IngelaAndin

Patch has passed first testings and has been assigned to be reviewed


I am a script, I am not human


OTP-Maintainer avatar Mar 03 '16 19:03 OTP-Maintainer

Any updates on this? Some projects and environments increasingly dictate IPv6 connectivity as a must and Erlang software effectively cannot comply if epmd cannot use IPv6 exclusively.

michaelklishin avatar Mar 14 '19 23:03 michaelklishin

A general principle we have is that we don't use conditional builds of Erlang code. (only debug, test can be conditional) We would like the epmd binary to support both IPv4 and IPv6 at the same time (or that we have 2 alternative ones where the correct one is started). I know that this is not the case right now.

Erlang can be started with erl -proto_dist inet6_tcp and this should be enough for talking IPv6 between E-nodes and E-nodes to epmd. It ought to work like that already now given that epmd is built with IPv6 support

KennethL avatar Apr 01 '19 14:04 KennethL

By the way I think I was wrong when I stated that EPMD can not support both IPv4 and IPv6 at the same time. It can do that. Then I don't see what is missing for running IPv6 end to end?

KennethL avatar Apr 01 '19 15:04 KennethL

Hi, We are having some problem with servers with only IPV6 interfaces, here you can find the discussion.

The bug is the follow:

# erl -proto_dist inet6_tcp -sname hello -kernel inet_dist_use_interface "{64827,62613,38481,3844,20564,255,65143,30576}"
Erlang/OTP 20 [erts-9.3.3.3] [source] [64-bit] [smp:2:2] [ds:2:2:10] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V9.3.3.3  (abort with ^G)
(hello@crowbar)1> net_adm:names(localhost).
{error,address}

Even the erl can bind using inet6_tcp the net_adm:names/1. does not work. So we had to change the network configuration, by adding ipv4 interface.

Is there something we can do to help on this issue, to get merged this PR? (that should solve the problem:) )

Thank you

Gsantomaggio avatar Apr 05 '19 06:04 Gsantomaggio

Looked inside this issue and I have seen that:

gabriele@linux-cnyy:~/otp-OTP-21.3.3> bin/erl -sname hello -proto_dist inet6_tcp
Erlang/OTP 21 [erts-10.3.2] [source] [64-bit] [smp:1:1] [ds:1:1:10] [async-threads:1] [hipe]

Eshell V10.3.2  (abort with ^G)
(hello@linux-cnyy)1> net_adm:names(localhost).
{error,address}
%% staring trace
(hello@linux-cnyy)6> net_adm:names(localhost).
(<0.89.0>) call inet_db:res_option(inet6)
(<0.89.0>) call inet_db:res_optname(inet6)
(<0.89.0>) returned from inet_db:res_optname/1 -> res_inet6
(<0.89.0>) call inet_db:db_get(res_inet6)
(<0.89.0>) returned from inet_db:db_get/1 -> false
(<0.89.0>) returned from inet_db:res_option/1 -> false
(<0.89.0>) call inet_db:res_option(lookup)
(<0.89.0>) call inet_db:res_optname(lookup)
(<0.89.0>) returned from inet_db:res_optname/1 -> res_lookup
(<0.89.0>) call inet_db:db_get(res_lookup)
(<0.89.0>) returned from inet_db:db_get/1 -> [native]
(<0.89.0>) returned from inet_db:res_option/1 -> [native]
(<0.89.0>) call inet_db:register_socket(#Port<0.11>,inet_tcp)
(<0.89.0>) returned from inet_db:register_socket/2 -> true
{error,address}
(hello@linux-cnyy)7>

The inet_db:res_option(inet6) returns false and the erl_epmd:open tries to use the ipv4 address:

(<0.105.0>) call erl_epmd:get_names({127,0,0,1})
(<0.105.0>) call erl_epmd:open({127,0,0,1})
(<0.105.0>) call erl_epmd:get_epmd_port()
(<0.105.0>) returned from erl_epmd:get_epmd_port/0 -> 4369
(<0.105.0>) call inet_db:register_socket(#Port<0.14>,inet_tcp)
(<0.105.0>) returned from inet_db:register_socket/2 -> true
(<0.105.0>) returned from erl_epmd:open/1 -> {error,econnrefused}
(<0.105.0>) returned from erl_epmd:get_names/1 -> {error,address}

By changing (only for test of course) gethostbyname/1 to:

gethostbyname(Name) ->
       gethostbyname_tm(Name, inet6, false).

The erl_epmd:open uses the ipv6 address

(hello@linux-cnyy)7> net_adm:names(localhost).
(<0.89.0>) call erl_epmd:names(localhost)
(<0.89.0>) call inet_db:res_option(lookup)
(<0.89.0>) call inet_db:res_optname(lookup)
(<0.89.0>) returned from inet_db:res_optname/1 -> res_lookup
(<0.89.0>) call inet_db:db_get(res_lookup)
(<0.89.0>) returned from inet_db:db_get/1 -> [native]
(<0.89.0>) returned from inet_db:res_option/1 -> [native]
(<0.89.0>) call erl_epmd:get_names({0,0,0,0,0,0,0,1})
(<0.89.0>) call erl_epmd:open({0,0,0,0,0,0,0,1})
(<0.89.0>) call erl_epmd:get_epmd_port()
.......

{ok,[{"hello",46579}]}

and it works.

So I agree with @kennethlakin we can support both, I don't know exactly why the inet_db:res_option(inet6) return false, maybe it is worth to investigate before merge this PR. ( unless i missed something).

thank you

Gsantomaggio avatar Apr 12 '19 12:04 Gsantomaggio

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

CLAassistant avatar Jul 02 '19 14:07 CLAassistant

Found this one, very helpful change. It is likely outdated, but is there any interest in reviving the PR? We experience same issues with IPv6 only servers.

max-au avatar Feb 22 '21 17:02 max-au