diff --git a/erlang.spec b/erlang.spec index 872dc21..af332c7 100644 --- a/erlang.spec +++ b/erlang.spec @@ -25,7 +25,7 @@ Name: erlang Version: %{upstream_ver} -Release: %{upstream_rel_for_rpm}.15%{?dist} +Release: %{upstream_rel_for_rpm}.16%{?dist} Summary: General-purpose programming language and runtime environment Group: Development/Languages @@ -2354,6 +2354,9 @@ useradd -r -g epmd -d /tmp -s /sbin/nologin \ %changelog +* Sun Feb 28 2016 Peter Lemenkov - R16B-03.16 +- Fixed issue with nodes registration over IPv6 + * Fri Feb 19 2016 Peter Lemenkov - R16B-03.15 - Add missing dependency diff --git a/otp-0023-epmd-support-IPv6-node-registration.patch b/otp-0023-epmd-support-IPv6-node-registration.patch index da81020..7d46bae 100644 --- a/otp-0023-epmd-support-IPv6-node-registration.patch +++ b/otp-0023-epmd-support-IPv6-node-registration.patch @@ -17,30 +17,22 @@ epmd ignores errors opening the socket if the protocol is not supported. Similarly, the epmd client will fall back to IPv4 if the IPv6 socket is not available. -The interaction between IPv4 and IPv6 sockets depends on the platform: - -* FreeBSD allows multiple "specific" sockets to bind the same port (such - as 2 sockets listening to the same port on ANY and the loopback). - Binding port 4369 to IPv4 and IPv6 sockets simulataneously is allowed. - -* Linux does not allow the same port to be bound by different sockets. - Setting the IPV6_V6ONLY socket option is required. - -* Windows - - The behaviour differs depending on the version of Windows: - - http://msdn.microsoft.com/en-us/library/windows/desktop/bb513665(v=vs.85).aspx - - According to the site, sockets on Windows XP with Service Pack 1 (SP1) - and Windows Server 2003 will only listen on either IPv4 or IPv6, so - creating two sockets is required to service IPv4 and IPv6 traffic on - the same port. The IPV6_V6ONLY socket option is not supported. - - For Windows Vista and later, a single socket can handle IPv4 and IPv6 - traffic for the same port. The IPV6_V6ONLY socket option is supported - and is enabled for IPv6 sockets by default. +Update the minimum supported version of Windows to Windows Vista to +support IPv6. +diff --git a/erts/configure.in b/erts/configure.in +index d9bc1ec..756f3cb 100644 +--- a/erts/configure.in ++++ b/erts/configure.in +@@ -424,7 +424,7 @@ case $host_os in + win32) + # The ethread library requires _WIN32_WINNT of at least 0x0403. + # -D_WIN32_WINNT=* from CPPFLAGS is saved in ETHR_DEFS. +- CPPFLAGS="$CPPFLAGS -D_WIN32_WINNT=0x0501 -DWINVER=0x0501" ++ CPPFLAGS="$CPPFLAGS -D_WIN32_WINNT=0x0600 -DWINVER=0x0600" + ;; + darwin*) + CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE" diff --git a/erts/doc/src/epmd.xml b/erts/doc/src/epmd.xml index 3e70054..3c9313e 100644 --- a/erts/doc/src/epmd.xml @@ -55,13 +47,18 @@ index 3e70054..3c9313e 100644

Starts the port mapper daemon

diff --git a/erts/doc/src/erl.xml b/erts/doc/src/erl.xml -index 528a2d9..dada3a1 100644 +index 528a2d9..0b8f821 100644 --- a/erts/doc/src/erl.xml +++ b/erts/doc/src/erl.xml -@@ -381,6 +381,28 @@ +@@ -381,6 +381,33 @@ similar to . See code(3).

++ ++ ++

Replaces the path specified in the boot script. See ++ script(4).

++
+ + +

Specify a protocol for Erlang distribution.

@@ -70,9 +67,9 @@ index 528a2d9..dada3a1 100644 + +

TCP over IPv4 (the default)

+
-+ inet_ssl ++ inet_tls + -+

distribution over SSL

++

distribution over TLS/SSL

+
+ inet6_tcp + @@ -101,7 +98,7 @@ index 1757fa9..ebae0a5 100644 /* These chouldn't be needed but for safety... */ diff --git a/erts/epmd/src/epmd_cli.c b/erts/epmd/src/epmd_cli.c -index 8817bde..c0b3729 100644 +index 8817bde..ea7dac7 100644 --- a/erts/epmd/src/epmd_cli.c +++ b/erts/epmd/src/epmd_cli.c @@ -135,19 +135,33 @@ void epmd_call(EpmdVars *g,int what) @@ -116,7 +113,7 @@ index 8817bde..c0b3729 100644 - goto error; + unsigned short sport = g->port; + -+#if defined(HAVE_IN6) && defined(AF_INET6) ++#if defined(EPMD6) + SET_ADDR6(address, in6addr_loopback, sport); + salen = sizeof(struct sockaddr_in6); + @@ -147,17 +144,10 @@ index 8817bde..c0b3729 100644 error: diff --git a/erts/epmd/src/epmd_int.h b/erts/epmd/src/epmd_int.h -index 363923e..e028449 100644 +index 363923e..c6d9173 100644 --- a/erts/epmd/src/epmd_int.h +++ b/erts/epmd/src/epmd_int.h -@@ -44,9 +44,14 @@ - #include - - #ifdef __WIN32__ -+# ifdef _WIN32_WINVER -+# undef _WIN32_WINVER -+# endif -+# define _WIN32_WINVER 0x0501 +@@ -47,6 +47,7 @@ # ifndef WINDOWS_H_INCLUDES_WINSOCK2_H # include # endif @@ -165,6 +155,17 @@ index 363923e..e028449 100644 # include # include #endif +@@ -114,6 +115,10 @@ + # include + #endif + ++#if defined(HAVE_IN6) && defined(AF_INET6) && defined(HAVE_INET_PTON) ++# define EPMD6 ++#endif ++ + /* ************************************************************************ */ + /* Replace some functions by others by making the function name a macro */ + @@ -167,33 +172,53 @@ /* ************************************************************************ */ /* Macros that let us use IPv6 */ @@ -193,7 +194,7 @@ index 363923e..e028449 100644 + +#define IS_ADDR_LOOPBACK(addr) ((addr).s_addr == htonl(INADDR_LOOPBACK)) + -+#if defined(HAVE_IN6) && defined(AF_INET6) ++#if defined(EPMD6) -#define EPMD_SOCKADDR_IN sockaddr_in6 -#define EPMD_IN_ADDR in6_addr @@ -247,7 +248,7 @@ index 363923e..e028449 100644 /* ************************************************************************ */ diff --git a/erts/epmd/src/epmd_srv.c b/erts/epmd/src/epmd_srv.c -index 78524a6..7b4d774 100644 +index 78524a6..28e30d4 100644 --- a/erts/epmd/src/epmd_srv.c +++ b/erts/epmd/src/epmd_srv.c @@ -70,6 +70,7 @@ static time_t current_time(EpmdVars*); @@ -284,7 +285,7 @@ index 78524a6..7b4d774 100644 + /* Always listen on the loopback. */ + SET_ADDR(iserv_addr[num_sockets],htonl(INADDR_LOOPBACK),sport); + num_sockets++; -+#if defined(HAVE_IN6) && defined(AF_INET6) ++#if defined(EPMD6) + SET_ADDR6(iserv_addr[num_sockets],in6addr_loopback,sport); + num_sockets++; +#endif @@ -304,9 +305,10 @@ index 78524a6..7b4d774 100644 + token = strtok(NULL,", ")) { - struct EPMD_IN_ADDR addr; -+ struct in_addr addr; - #ifdef HAVE_INET_PTON +-#ifdef HAVE_INET_PTON - int ret; ++ struct in_addr addr; ++#if defined(EPMD6) + struct in6_addr addr6; + struct sockaddr_storage *sa = &iserv_addr[num_sockets]; @@ -337,7 +339,7 @@ index 78524a6..7b4d774 100644 epmd_cleanup_exit(g,1); } -+#if defined(HAVE_IN6) && defined(AF_INET6) ++#if defined(EPMD6) + if (sa->ss_family == AF_INET6 && IN6_IS_ADDR_LOOPBACK(&addr6)) + continue; + @@ -346,10 +348,10 @@ index 78524a6..7b4d774 100644 if (IS_ADDR_LOOPBACK(addr)) - loopback_ok = 1; + continue; -+ -+ num_sockets++; - if (num_sockets - loopback_ok == MAX_LISTEN_SOCKETS - 1) ++ num_sockets++; ++ + if (num_sockets >= MAX_LISTEN_SOCKETS) { dbg_tty_printf(g,0,"cannot listen on more than %d IP addresses", @@ -374,7 +376,7 @@ index 78524a6..7b4d774 100644 - num_sockets = 1; + SET_ADDR(iserv_addr[num_sockets],htonl(INADDR_ANY),sport); + num_sockets++; -+#if defined(HAVE_IN6) && defined(AF_INET6) ++#if defined(EPMD6) + SET_ADDR6(iserv_addr[num_sockets],in6addr_any,sport); + num_sockets++; +#endif @@ -387,7 +389,7 @@ index 78524a6..7b4d774 100644 { - if ((listensock[i] = socket(FAMILY,SOCK_STREAM,0)) < 0) + struct sockaddr *sa = (struct sockaddr *)&iserv_addr[i]; -+#if defined(HAVE_IN6) && defined(AF_INET6) ++#if defined(EPMD6) + size_t salen = (sa->sa_family == AF_INET6 ? + sizeof(struct sockaddr_in6) : + sizeof(struct sockaddr_in)); @@ -398,7 +400,6 @@ index 78524a6..7b4d774 100644 + if ((listensock[i] = socket(sa->sa_family,SOCK_STREAM,0)) < 0) { - dbg_perror(g,"error opening stream socket"); -- epmd_cleanup_exit(g,1); + switch (errno) { + case EAFNOSUPPORT: + case EPROTONOSUPPORT: @@ -407,9 +408,8 @@ index 78524a6..7b4d774 100644 + dbg_perror(g,"error opening stream socket"); + epmd_cleanup_exit(g,1); + } - } - g->listenfd[i] = listensock[i]; -- ++ } ++ g->listenfd[bound++] = listensock[i]; + +#if HAVE_DECL_IPV6_V6ONLY + opt = 1; @@ -418,8 +418,10 @@ index 78524a6..7b4d774 100644 + sizeof(opt)) <0) + { + dbg_perror(g,"can't set IPv6 only socket option"); -+ epmd_cleanup_exit(g,1); -+ } + epmd_cleanup_exit(g,1); + } +- g->listenfd[i] = listensock[i]; +- +#endif + /* @@ -435,28 +437,30 @@ index 78524a6..7b4d774 100644 { if (errno == EADDRINUSE) { -@@ -388,12 +433,20 @@ void run(EpmdVars *g) - } - } - -+ bound++; -+ - if(listen(listensock[i], SOMAXCONN) < 0) { - dbg_perror(g,"failed to listen on socket"); - epmd_cleanup_exit(g,1); +@@ -394,6 +439,11 @@ void run(EpmdVars *g) } select_fd_set(g, listensock[i]); } -+ + if (bound == 0) { + dbg_perror(g,"unable to bind any address"); + epmd_cleanup_exit(g,1); + } -+ ++ num_sockets = bound; #ifdef HAVE_SYSTEMD_SD_DAEMON_H } sd_notifyf(0, "READY=1\n" -@@ -1001,15 +1054,6 @@ static int conn_open(EpmdVars *g,int fd) +@@ -438,8 +488,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() +@@ -1001,15 +1051,6 @@ static int conn_open(EpmdVars *g,int fd) for (i = 0; i < g->max_conn; i++) { if (g->conn[i].open == EPMD_FALSE) { @@ -472,7 +476,7 @@ index 78524a6..7b4d774 100644 g->active_conn++; s = &g->conn[i]; -@@ -1020,20 +1064,7 @@ static int conn_open(EpmdVars *g,int fd) +@@ -1020,20 +1061,7 @@ static int conn_open(EpmdVars *g,int fd) s->open = EPMD_TRUE; s->keep = EPMD_FALSE; @@ -494,7 +498,7 @@ index 78524a6..7b4d774 100644 dbg_tty_printf(g,2,(s->local_peer) ? "Local peer connected" : "Non-local peer connected"); -@@ -1041,7 +1072,7 @@ static int conn_open(EpmdVars *g,int fd) +@@ -1041,7 +1069,7 @@ static int conn_open(EpmdVars *g,int fd) s->got = 0; s->mod_time = current_time(g); /* Note activity */ @@ -503,7 +507,7 @@ index 78524a6..7b4d774 100644 if (s->buf == NULL) { dbg_printf(g,0,"epmd: Insufficient memory"); -@@ -1059,6 +1090,60 @@ static int conn_open(EpmdVars *g,int fd) +@@ -1059,6 +1087,60 @@ static int conn_open(EpmdVars *g,int fd) return EPMD_FALSE; } @@ -515,7 +519,7 @@ index 78524a6..7b4d774 100644 + struct sockaddr_in *si4 = (struct sockaddr_in *)&si; + struct sockaddr_in *di4 = (struct sockaddr_in *)&di; + -+#if defined(HAVE_IN6) && defined(AF_INET6) ++#if defined(EPMD6) + struct sockaddr_in6 *si6 = (struct sockaddr_in6 *)&si; + struct sockaddr_in6 *di6 = (struct sockaddr_in6 *)&di; +#endif @@ -537,7 +541,7 @@ index 78524a6..7b4d774 100644 + + /* 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 defined(EPMD6) + if (si.ss_family == AF_INET6 && IN6_IS_ADDR_LOOPBACK(&(si6->sin6_addr))) + return EPMD_TRUE; + @@ -550,13 +554,13 @@ index 78524a6..7b4d774 100644 + if (getsockname(fd,(struct sockaddr*) &di,&st)) + return EPMD_FALSE; + -+#if defined(HAVE_IN6) && defined(AF_INET6) ++#if defined(EPMD6) + if (si.ss_family == AF_INET6) + return IN6_ARE_ADDR_EQUAL( &(si6->sin6_addr), &(di6->sin6_addr)); + if (si.ss_family == AF_INET) +#endif + return si4->sin_addr.s_addr == di4->sin_addr.s_addr; -+#if defined(HAVE_IN6) && defined(AF_INET6) ++#if defined(EPMD6) + return EPMD_FALSE; +#endif +} @@ -565,7 +569,7 @@ index 78524a6..7b4d774 100644 { int i; diff --git a/erts/epmd/test/epmd_SUITE.erl b/erts/epmd/test/epmd_SUITE.erl -index cc24a55..ddfe5ab 100644 +index cc24a55..8dfc21f 100644 --- a/erts/epmd/test/epmd_SUITE.erl +++ b/erts/epmd/test/epmd_SUITE.erl @@ -42,6 +42,7 @@ @@ -611,7 +615,7 @@ index cc24a55..ddfe5ab 100644 register_names_1(doc) -> ["Register and unregister two nodes"]; register_names_1(suite) -> -@@ -238,13 +258,18 @@ register_node(Name) -> +@@ -238,13 +258,14 @@ register_node(Name) -> register_node(Name,Port) -> register_node_v2(Port,$M,0,5,5,Name,""). @@ -619,19 +623,20 @@ index cc24a55..ddfe5ab 100644 + register_node_v2({0,0,0,0,0,0,0,1},?DUMMY_PORT,$M,0,5,5,Name,""). + register_node_v2(Port, NodeType, Prot, HVsn, LVsn, Name, Extra) -> +- Utf8Name = unicode:characters_to_binary(Name), +- Req = [?EPMD_ALIVE2_REQ, put16(Port), NodeType, Prot, +- put16(HVsn), put16(LVsn), +- put16(size(Utf8Name)), binary_to_list(Utf8Name), +- size16(Extra), Extra], +- case send_req(Req) of + register_node_v2("localhost", Port, NodeType, Prot, HVsn, LVsn, Name, Extra). +register_node_v2(Addr, Port, NodeType, Prot, HVsn, LVsn, Name, Extra) -> - Utf8Name = unicode:characters_to_binary(Name), - Req = [?EPMD_ALIVE2_REQ, put16(Port), NodeType, Prot, - put16(HVsn), put16(LVsn), - put16(size(Utf8Name)), binary_to_list(Utf8Name), - size16(Extra), Extra], -- case send_req(Req) of ++ Req = alive2_req(Port, NodeType, Prot, HVsn, LVsn, Name, Extra), + case send_req(Req, Addr) of {ok,Sock} -> case recv(Sock,4) of {ok, [?EPMD_ALIVE2_RESP,_Res=0,_C0,_C1]} -> -@@ -1129,7 +1154,9 @@ send_direct(Sock, Bytes) -> +@@ -1129,7 +1150,9 @@ send_direct(Sock, Bytes) -> end. send_req(Req) -> @@ -642,6 +647,19 @@ index cc24a55..ddfe5ab 100644 {ok,Sock} -> case send(Sock, [size16(Req), Req]) of ok -> +diff --git a/lib/erl_interface/configure.in b/lib/erl_interface/configure.in +index d511f2e..99ee635 100644 +--- a/lib/erl_interface/configure.in ++++ b/lib/erl_interface/configure.in +@@ -250,7 +250,7 @@ case "$threads_disabled" in + ;; + win32_threads) + EI_THREADS="true" +- THR_DEFS="$THR_DEFS -D_WIN32_WINNT=0x0500 -DWINVER=0x0500" ++ THR_DEFS="$THR_DEFS -D_WIN32_WINNT=0x0600 -DWINVER=0x0600" + ;; + pthread) + EI_THREADS="true" diff --git a/lib/kernel/src/erl_epmd.erl b/lib/kernel/src/erl_epmd.erl index 91af49f..21a3dec 100644 --- a/lib/kernel/src/erl_epmd.erl @@ -694,3 +712,26 @@ index 91af49f..21a3dec 100644 {ok, Socket} -> Name = to_string(NodeName), Extra = "", +diff --git a/lib/wx/configure.in b/lib/wx/configure.in +index 3756786..be73888 100755 +--- a/lib/wx/configure.in ++++ b/lib/wx/configure.in +@@ -163,14 +163,14 @@ case $host_os in + CPPFLAGS="$CPPFLAGS -D_MACOSX $PTHR_CFLAGS" + ;; + mingw32) +- CFLAGS="$CFLAGS -DWIN32 -DWINVER=0x0500 -D_WINDOWS -D_UNICODE -DUNICODE" +- CPPFLAGS="$CPPFLAGS -D_WIN32_WINNT=0x0500" ++ CFLAGS="$CFLAGS -DWIN32 -DWINVER=0x0600 -D_WINDOWS -D_UNICODE -DUNICODE" ++ CPPFLAGS="$CPPFLAGS -D_WIN32_WINNT=0x0600" + AC_MSG_WARN([Reverting to 32-bit time_t]) + CPPFLAGS="$CPPFLAGS -D_USE_32BIT_TIME_T" + ;; + win32) +- CFLAGS="$CFLAGS -DWIN32 -DWINVER=0x0500 -D_WINDOWS -D_UNICODE -DUNICODE" +- CPPFLAGS="$CPPFLAGS -D_WIN32_WINNT=0x0500" ++ CFLAGS="$CFLAGS -DWIN32 -DWINVER=0x0600 -D_WINDOWS -D_UNICODE -DUNICODE" ++ CPPFLAGS="$CPPFLAGS -D_WIN32_WINNT=0x0600" + ;; + *) + CFLAGS="$CFLAGS -Wno-deprecated-declarations"