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"