|
Allow IPv6 nodes to register with and query epmd. epmd now listens on
an IPv6 socket by default (if IPv6 support is available). Reported-By: Boris Mühmer --- erts/epmd/src/epmd_int.h | 2 +- erts/epmd/src/epmd_srv.c | 66 +++++++++++++++++++++++------------- lib/kernel/src/erl_epmd.erl | 18 +++++++--- lib/kernel/src/inet6_tcp_dist.erl | 2 +- 4 files changed, 56 insertions(+), 32 deletions(-) diff --git a/erts/epmd/src/epmd_int.h b/erts/epmd/src/epmd_int.h index 2a0de4d..850607b 100644 --- a/erts/epmd/src/epmd_int.h +++ b/erts/epmd/src/epmd_int.h @@ -165,7 +165,7 @@ /* ************************************************************************ */ /* Macros that let us use IPv6 */ -#if defined(HAVE_IN6) && defined(AF_INET6) && defined(EPMD6) +#if defined(HAVE_IN6) && defined(AF_INET6) #define EPMD_SOCKADDR_IN sockaddr_in6 #define EPMD_IN_ADDR in6_addr diff --git a/erts/epmd/src/epmd_srv.c b/erts/epmd/src/epmd_srv.c index 4d9b454..ea7caf2 100644 --- a/erts/epmd/src/epmd_srv.c +++ b/erts/epmd/src/epmd_srv.c @@ -69,6 +69,7 @@ static time_t current_time(EpmdVars*); static Connection *conn_init(EpmdVars*); static int conn_open(EpmdVars*,int); +static int conn_local_access_check(int fd); static int conn_close_fd(EpmdVars*,int); static void node_init(EpmdVars*); @@ -122,7 +123,7 @@ void run(EpmdVars *g) epmd_cleanup_exit(g,1); } else if (ret == 0) -#elif !defined(EPMD6) +#else if ((addr.EPMD_S_ADDR = inet_addr(token)) == INADDR_NONE) #endif { @@ -808,15 +809,6 @@ 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; -#ifdef HAVE_SOCKLEN_T - socklen_t st; -#else - int st; -#endif - st = sizeof(si); - g->active_conn++; s = &g->conn[i]; @@ -827,20 +819,7 @@ static int conn_open(EpmdVars *g,int fd) s->open = EPMD_TRUE; s->keep = EPMD_FALSE; - /* Determine if connection is from localhost */ - if (getpeername(s->fd,(struct sockaddr*) &si,&st) || - st < sizeof(si)) { - /* 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)); - } + s->local_peer = conn_local_access_check(s->fd); dbg_tty_printf(g,2,(s->local_peer) ? "Local peer connected" : "Non-local peer connected"); @@ -866,6 +845,45 @@ static int conn_open(EpmdVars *g,int fd) return EPMD_FALSE; } +static int conn_local_access_check(int fd) +{ + struct EPMD_SOCKADDR_IN si; + struct EPMD_SOCKADDR_IN di; +#ifdef HAVE_SOCKLEN_T + socklen_t st; +#else + int st; +#endif + st = sizeof(si); + + /* Determine if connection is from localhost */ + if (getpeername(fd,(struct sockaddr*) &si,&st) || + st < sizeof(si)) { + /* Failure to get peername is regarded as non local host */ + return EPMD_FALSE; + } + + /* Only 127.x.x.x and connections from the host's IP address + allowed, no false positives */ +#if defined(HAVE_IN6) && defined(AF_INET6) + if (IN6_IS_ADDR_LOOPBACK(&si.sin6_addr)) + return EPMD_TRUE; +#else + if ((((unsigned) ntohl(si.sin_addr.s_addr)) & 0xFF000000U) == + 0x7F000000U) + return EPMD_TRUE; +#endif + + if (getsockname(fd,(struct sockaddr*) &di,&st)) + return EPMD_FALSE; + +#if defined(HAVE_IN6) && defined(AF_INET6) + return IN6_ARE_ADDR_EQUAL(&si.sin6_addr, &di.sin6_addr); +#else + return si.sin_addr.s_addr == di.sin_addr.s_addr; +#endif +} + static int conn_close_fd(EpmdVars *g,int fd) { int i; diff --git a/lib/kernel/src/erl_epmd.erl b/lib/kernel/src/erl_epmd.erl index 91af49f..e9d1caa 100644 --- a/lib/kernel/src/erl_epmd.erl +++ b/lib/kernel/src/erl_epmd.erl @@ -31,7 +31,7 @@ %% External exports -export([start/0, start_link/0, stop/0, port_please/2, port_please/3, names/0, names/1, - register_node/2, open/0, open/1, open/2]). + register_node/2, register_node/3, open/0, open/1, open/2]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, @@ -106,7 +106,9 @@ names1(HostName) -> register_node(Name, PortNo) -> - gen_server:call(erl_epmd, {register, Name, PortNo}, infinity). + register_node(Name, PortNo, inet). +register_node(Name, PortNo, Family) -> + gen_server:call(erl_epmd, {register, Name, PortNo, Family}, infinity). %%%---------------------------------------------------------------------- %%% Callback functions from gen_server @@ -124,10 +126,10 @@ init(_) -> -spec handle_call(calls(), term(), state()) -> {'reply', term(), state()} | {'stop', 'shutdown', 'ok', state()}. -handle_call({register, Name, PortNo}, _From, State) -> +handle_call({register, Name, PortNo, Family}, _From, State) -> case State#state.socket of P when P < 0 -> - case do_register_node(Name, PortNo) of + case do_register_node(Name, PortNo, Family) of {alive, Socket, Creation} -> S = State#state{socket = Socket, port_no = PortNo, @@ -210,8 +212,12 @@ open({A,B,C,D,E,F,G,H}=EpmdAddr, Timeout) when ?ip6(A,B,C,D,E,F,G,H) -> close(Socket) -> gen_tcp:close(Socket). -do_register_node(NodeName, TcpPort) -> - case open() of +do_register_node(NodeName, TcpPort, Family) -> + Localhost = case Family of + inet -> {127,0,0,1}; + inet6 -> {0,0,0,0,0,0,0,1} + end, + case open(Localhost) of {ok, Socket} -> Name = to_string(NodeName), Extra = "", diff --git a/lib/kernel/src/inet6_tcp_dist.erl b/lib/kernel/src/inet6_tcp_dist.erl index b9c4fa6..0b5fb44 100644 --- a/lib/kernel/src/inet6_tcp_dist.erl +++ b/lib/kernel/src/inet6_tcp_dist.erl @@ -71,7 +71,7 @@ listen(Name) -> {ok, Socket} -> TcpAddress = get_tcp_address(Socket), {_,Port} = TcpAddress#net_address.address, - {ok, Creation} = erl_epmd:register_node(Name, Port), + {ok, Creation} = erl_epmd:register_node(Name, Port, inet6), {ok, {Socket, TcpAddress, Creation}}; Error -> Error -- 1.7.0.4 _______________________________________________ erlang-patches mailing list [hidden email] http://erlang.org/mailman/listinfo/erlang-patches |
|
Please use the second version of this patch. Sorry, of course I didn't notice a change I'd wanted to make until after I sent it the first time. On Fri, Jun 03, 2011 at 10:49:25AM -0400, Michael Santos wrote: > Allow IPv6 nodes to register with and query epmd. epmd now listens on > an IPv6 socket by default (if IPv6 support is available). > > Reported-By: Boris Mühmer _______________________________________________ erlang-patches mailing list [hidden email] http://erlang.org/mailman/listinfo/erlang-patches |
|
In reply to this post by Michael Santos-2
On Fri, Jun 03, 2011 at 10:49:25AM -0400, Michael Santos wrote:
> Allow IPv6 nodes to register with and query epmd. epmd now listens on > an IPv6 socket by default (if IPv6 support is available). > > Reported-By: Boris Mühmer Thank you. I have included your patch into 'pu'. -- / Raimo Niskanen, Erlang/OTP, Ericsson AB _______________________________________________ erlang-patches mailing list [hidden email] http://erlang.org/mailman/listinfo/erlang-patches |
| Powered by Nabble | Edit this page |
