Skip to content

Commit

Permalink
Conf option to have an end to end ipv6 otp release
Browse files Browse the repository at this point in the history
 - 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 configures:

- the -DEPMD6 CFLAG for epmd compilation
- the default proto_dist (without init arg) to "inet6_tcp"
- the epmd connection ip to "::1"
  • Loading branch information
awetzel committed Feb 4, 2015
1 parent 42d6afe commit cf835a5
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 14 deletions.
11 changes: 11 additions & 0 deletions configure.in
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,10 @@ AC_ARG_ENABLE(native-libs,
AS_HELP_STRING([--enable-native-libs],
[compile Erlang libraries to native code]))

AC_ARG_ENABLE(epmd-ipv6,
AS_HELP_STRING([--enable-epmd-ipv6],
[enable epmd ipv6 communication instead of ipv4]))

AC_ARG_WITH(dynamic-trace,
AS_HELP_STRING([--with-dynamic-trace={dtrace|systemtap}],
[specify use of dynamic trace framework, dtrace or systemtap])
Expand Down Expand Up @@ -419,6 +423,13 @@ if test X${enable_native_libs} = Xyes -a X${enable_hipe} != Xno; then
fi
AC_SUBST(NATIVE_LIBS_ENABLED)

EPMD_IPV6_ENABLED=
if test X${enable_epmd_ipv6} = Xyes; then
CFLAGS="-DEPMD6 $CFLAGS"
export CFLAGS
EPMD_IPV6_ENABLED=yes
fi
AC_SUBST(EPMD_IPV6_ENABLED)

rm -f $ERL_TOP/lib/SKIP-APPLICATIONS
for app in `cd lib && ls -d *`; do
Expand Down
12 changes: 12 additions & 0 deletions erts/configure.in
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,10 @@ AC_ARG_ENABLE(native-libs,
AS_HELP_STRING([--enable-native-libs],
[compile Erlang libraries to native code]))

AC_ARG_ENABLE(epmd-ipv6,
AS_HELP_STRING([--enable-epmd-ipv6],
[enable epmd ipv6 communication instead of ipv4]))

AC_ARG_ENABLE(fp-exceptions,
AS_HELP_STRING([--enable-fp-exceptions],
[use hardware floating point exceptions (default if hipe enabled)]),
Expand Down Expand Up @@ -3502,6 +3506,14 @@ if test X${enable_native_libs} = Xyes -a X${HIPE_ENABLED} = Xyes; then
fi
AC_SUBST(NATIVE_LIBS_ENABLED)

EPMD_IPV6_ENABLED=
if test X${enable_epmd_ipv6} = Xyes; then
CFLAGS="-DEPMD6 $CFLAGS"
export CFLAGS
EPMD_IPV6_ENABLED=yes
fi
AC_SUBST(EPMD_IPV6_ENABLED)

#
# Check if HiPE should use a standard installation of perfctr.
#
Expand Down
35 changes: 24 additions & 11 deletions erts/epmd/src/epmd_srv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1006,8 +1006,8 @@ static int conn_open(EpmdVars *g,int fd)

for (i = 0; i < g->max_conn; i++) {
if (g->conn[i].open == EPMD_FALSE) {
struct sockaddr_in si;
struct sockaddr_in di;
struct sockaddr_storage si;
struct sockaddr_storage di;
#ifdef HAVE_SOCKLEN_T
socklen_t st;
#else
Expand All @@ -1026,18 +1026,31 @@ static int conn_open(EpmdVars *g,int fd)
s->keep = EPMD_FALSE;

/* Determine if connection is from localhost */
if (getpeername(s->fd,(struct sockaddr*) &si,&st) ||
st < sizeof(si)) {
if (getpeername(s->fd,(struct sockaddr*) &si,&st)) {
/* Failure to get peername is regarded as non local host */
s->local_peer = EPMD_FALSE;
} else {
/* Only 127.x.x.x and connections from the host's IP address
allowed, no false positives */
s->local_peer =
(((((unsigned) ntohl(si.sin_addr.s_addr)) & 0xFF000000U) ==
0x7F000000U) ||
(getsockname(s->fd,(struct sockaddr*) &di,&st) ?
EPMD_FALSE : si.sin_addr.s_addr == di.sin_addr.s_addr));
if (si.ss_family == AF_INET) {
struct sockaddr_in *si4 = (struct sockaddr_in *)&si;
struct sockaddr_in *di4 = (struct sockaddr_in *)&di;
/* Only 127.x.x.x and connections from the host's IP address
allowed, no false positives */
s->local_peer =
(((((unsigned) ntohl(si4->sin_addr.s_addr)) & 0xFF000000U) ==
0x7F000000U) ||
(getsockname(s->fd,(struct sockaddr*) di4,&st) ?
EPMD_FALSE : si4->sin_addr.s_addr == di4->sin_addr.s_addr));
} else { // AF_INET6
struct sockaddr_in6 *si6 = (struct sockaddr_in6 *)&si;
struct sockaddr_in6 *di6 = (struct sockaddr_in6 *)&di;
/* The same rule than for AF_INET, but only ::1 is local in ipv6 */
static const unsigned char inet6_localhost[] =
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
s->local_peer =
((memcmp(si6->sin6_addr.s6_addr, inet6_localhost, 16) == 0) ||
(getsockname(s->fd,(struct sockaddr*) di6,&st) ? EPMD_FALSE :
(memcmp(si6->sin6_addr.s6_addr,di6->sin6_addr.s6_addr,16) == 0)));
}
}
dbg_tty_printf(g,2,(s->local_peer) ? "Local peer connected" :
"Non-local peer connected");
Expand Down
8 changes: 7 additions & 1 deletion lib/kernel/src/erl_epmd.erl
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@
-define(port_please_failure2(Term), noop).
-endif.

-ifdef(EPMD_IPV6).
-define(DEFAULT_EPMD_IP, {0,0,0,0,0,0,0,1}).
-else.
-define(DEFAULT_EPMD_IP, {127,0,0,1}).
-endif.

%% External exports
-export([start/0, start_link/0, stop/0, port_please/2,
port_please/3, names/0, names/1,
Expand Down Expand Up @@ -190,7 +196,7 @@ get_epmd_port() ->
%%
%% Epmd socket
%%
open() -> open({127,0,0,1}). % The localhost IP address.
open() -> open(?DEFAULT_EPMD_IP). % The localhost IP address.

open({A,B,C,D}=EpmdAddr) when ?ip(A,B,C,D) ->
gen_tcp:connect(EpmdAddr, get_epmd_port(), [inet]);
Expand Down
10 changes: 8 additions & 2 deletions lib/kernel/src/net_kernel.erl
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@
-define(tckr_dbg(X), ok).
-endif.

-ifdef(EPMD_IPV6).
-define(DEFAULT_PROTO_DIST, "inet6_tcp").
-else.
-define(DEFAULT_PROTO_DIST, "inet_tcp").
-endif.

%% User Interface Exports
-export([start/1, start_link/1, stop/0,
kernel_apply/3,
Expand Down Expand Up @@ -1275,7 +1281,7 @@ protocol_childspecs() ->
{ok, [Protos]} ->
protocol_childspecs(Protos);
_ ->
protocol_childspecs(["inet_tcp"])
protocol_childspecs([?DEFAULT_PROTO_DIST])
end.

protocol_childspecs([]) ->
Expand Down Expand Up @@ -1311,7 +1317,7 @@ start_protos(Name,Node) ->
{ok, [Protos]} ->
start_protos(Name,Protos, Node);
_ ->
start_protos(Name,["inet_tcp"], Node)
start_protos(Name,[?DEFAULT_PROTO_DIST], Node)
end.

start_protos(Name,Ps, Node) ->
Expand Down
11 changes: 11 additions & 0 deletions make/otp.mk.in
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ DUBIOUS_ORIGINS = /undefined/environment/
HIPE_ENABLED=@HIPE_ENABLED@
NATIVE_LIBS_ENABLED=@NATIVE_LIBS_ENABLED@

# ----------------------------------------------------
# Epmd default IPV6
# ----------------------------------------------------

EPMD_IPV6_ENABLED=@EPMD_IPV6_ENABLED@

# ----------------------------------------------------
# Command macros
# ----------------------------------------------------
Expand Down Expand Up @@ -98,6 +104,11 @@ else
ERL_COMPILE_FLAGS += +debug_info
endif
endif

ifeq ($(EPMD_IPV6_ENABLED),yes)
ERL_COMPILE_FLAGS += -DEPMD_IPV6
endif

ERLC_WFLAGS = -W
ERLC = erlc $(ERLC_WFLAGS) $(ERLC_FLAGS)
ERL = erl -boot start_clean
Expand Down

0 comments on commit cf835a5

Please sign in to comment.