Bug 92620 - jdk14 under the environment where net.inet6.ip6.v6only=1
Summary: jdk14 under the environment where net.inet6.ip6.v6only=1
Status: Closed FIXED
Alias: None
Product: Ports & Packages
Classification: Unclassified
Component: Individual Port(s) (show other bugs)
Version: Latest
Hardware: Any Any
: Normal Affects Only Me
Assignee: Greg Lewis
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-01-31 14:50 UTC by Hajimu UMEMOTO
Modified: 2006-10-08 20:30 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Hajimu UMEMOTO freebsd_committer freebsd_triage 2006-01-31 14:50:02 UTC
When we use an IPv4 with ports/java/jdk14 built with WITH_IPV6=YES, we
need to set net.inet6.ip6.v6only to 0.  It is too restrictive.

Fix: We have an IPV6_V6ONLY socket option to allow an IPv4-mapped IPv6
address per socket basis.  Here is a patch to use an IPV6_V6ONLY
socket option.  Please put it into jdk14/files as something like
patch-v6only.



--
Hajimu UMEMOTO @ Internet Mutual Aid Society Yokohama, Japan
ume@mahoroba.org  ume@{,jp.}FreeBSD.org
http://www.imasy.org/~ume/--v5OyD0Fr5WIMJMqG9rvdE1vAHc5RtuvRwZ7XjPd5AUijum0Y
Content-Type: text/plain; name="file.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="file.diff"

Index: ../../j2se/src/solaris/native/java/net/PlainDatagramSocketImpl.c
diff -u -p ../../j2se/src/solaris/native/java/net/PlainDatagramSocketImpl.c.orig ../../j2se/src/solaris/native/java/net/PlainDatagramSocketImpl.c
--- ../../j2se/src/solaris/native/java/net/PlainDatagramSocketImpl.c.orig	Mon Oct 31 21:54:39 2005
+++ ../../j2se/src/solaris/native/java/net/PlainDatagramSocketImpl.c	Tue Nov  1 13:13:05 2005
@@ -226,8 +226,15 @@ Java_java_net_PlainDatagramSocketImpl_bi
 
     NET_InetAddressToSockaddr(env, iaObj, localport, (struct sockaddr *)&him, &len);
 #if defined(_ALLBSD_SOURCE)
-            if (cannotMap4to6(env, iaObj))
-                return;
+#if defined(IPV6_V6ONLY)
+    if (((struct sockaddr *)&him)->sa_family == AF_INET6) {
+	int t = 0;
+	JVM_SetSockOpt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&t, sizeof(t));
+    }
+#else
+    if (cannotMap4to6(env, iaObj))
+	return;
+#endif /* IPV6_V6ONLY */
 #endif /* _ALLBSD_SOURCE */
 
 
@@ -292,8 +299,15 @@ Java_java_net_PlainDatagramSocketImpl_co
 
     NET_InetAddressToSockaddr(env, address, port, (struct sockaddr *)&rmtaddr, &len);
 #if defined(_ALLBSD_SOURCE)
-            if (cannotMap4to6(env, address))
-                return;
+#if defined(IPV6_V6ONLY)
+    if (((struct sockaddr *)&rmtaddr)->sa_family == AF_INET6) {
+	int t = 0;
+	JVM_SetSockOpt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&t, sizeof(t));
+    }
+#else
+    if (cannotMap4to6(env, address))
+	return;
+#endif /* IPV6_V6ONLY */
 #endif /* _ALLBSD_SOURCE */
 
 
@@ -2191,11 +2205,18 @@ static void mcast_join_leave(JNIEnv *env
 	jbyte caddr[16];
 	jint family;
 	jint address;
+#if defined(_ALLBSD_SOURCE) && defined(IPV6_V6ONLY)
+	int t = 0;
+#endif
 	family = (*env)->GetIntField(env, iaObj, ia_familyID) == IPv4? AF_INET : AF_INET6;
 
 #if defined(_ALLBSD_SOURCE)
-	    if (cannotMap4to6(env, iaObj))
-		return;
+#if defined(IPV6_V6ONLY)
+	JVM_SetSockOpt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&t, sizeof(t));
+#else
+	if (cannotMap4to6(env, iaObj))
+	    return;
+#endif /* IPV6_V6ONLY */
 #endif /* _ALLBSD_SOURCE */
 
 	if (family == AF_INET) { /* will convert to IPv4-mapped address */
Index: ../../j2se/src/solaris/native/java/net/PlainSocketImpl.c
diff -u -p ../../j2se/src/solaris/native/java/net/PlainSocketImpl.c.orig ../../j2se/src/solaris/native/java/net/PlainSocketImpl.c
--- ../../j2se/src/solaris/native/java/net/PlainSocketImpl.c.orig	Mon Oct 31 21:54:39 2005
+++ ../../j2se/src/solaris/native/java/net/PlainSocketImpl.c	Tue Nov  1 13:11:57 2005
@@ -323,8 +323,15 @@ Java_java_net_PlainSocketImpl_socketConn
     /* connect */
     NET_InetAddressToSockaddr(env, iaObj, port, (struct sockaddr *)&him, &len);
 #if defined(_ALLBSD_SOURCE)
-            if (cannotMap4to6(env, iaObj))
-                return;
+#if defined(IPV6_V6ONLY)
+    if (((struct sockaddr *)&him)->sa_family == AF_INET6) {
+	int t = 0;
+	JVM_SetSockOpt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&t, sizeof(t));
+    }
+#else
+    if (cannotMap4to6(env, iaObj))
+	return;
+#endif /* IPV6_V6ONLY */
 #endif /* _ALLBSD_SOURCE */
 
 #ifdef AF_INET6
@@ -579,8 +586,15 @@ Java_java_net_PlainSocketImpl_socketBind
     /* bind */
     NET_InetAddressToSockaddr(env, iaObj, localport, (struct sockaddr *)&him, &len);
 #if defined(_ALLBSD_SOURCE)
-            if (cannotMap4to6(env, iaObj))
-                return;
+#if defined(IPV6_V6ONLY)
+    if (((struct sockaddr *)&him)->sa_family == AF_INET6) {
+	int t = 0;
+	JVM_SetSockOpt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&t, sizeof(t));
+    }
+#else
+    if (cannotMap4to6(env, iaObj))
+	return;
+#endif /* IPV6_V6ONLY */
 #endif /* _ALLBSD_SOURCE */
 
     if (NET_Bind(fd, (struct sockaddr *)&him, len) < 0) {
Index: ../../j2se/src/solaris/native/java/net/net_util_md.c
diff -u -p ../../j2se/src/solaris/native/java/net/net_util_md.c.orig ../../j2se/src/solaris/native/java/net/net_util_md.c
--- ../../j2se/src/solaris/native/java/net/net_util_md.c.orig	Mon Oct 31 21:54:39 2005
+++ ../../j2se/src/solaris/native/java/net/net_util_md.c	Tue Nov  1 13:14:35 2005
@@ -1129,7 +1129,7 @@ NET_Bind(int fd, struct sockaddr *him, i
     return rv;
 }
 
-#if defined(_ALLBSD_SOURCE)
+#if defined(_ALLBSD_SOURCE) && !defined(IPV6_V6ONLY)
 
 /*
  * If net.inet6.ip6.v6only is set to 1, then IPv4 mapped addresses usage
Index: ../../j2se/src/solaris/native/java/net/net_util_md.h
diff -u ../../j2se/src/solaris/native/java/net/net_util_md.h.orig ../../j2se/src/solaris/native/java/net/net_util_md.h
--- ../../j2se/src/solaris/native/java/net/net_util_md.h.orig	Mon Oct 31 21:54:39 2005
+++ ../../j2se/src/solaris/native/java/net/net_util_md.h	Tue Nov  1 13:15:39 2005
@@ -24,6 +24,9 @@
 #endif
 #endif /* !_ALLBSD_SOURCE */
 
+#if defined(IPV6_V6ONLY) && defined(__OpenBSD__)
+#undef IPV6_V6ONLY
+#endif
 /*
  * Linux header files define sockaddr_in6 incorrectly (missing the
  * sin6_scope_id field) so we use our own definition.
@@ -144,7 +147,7 @@
 /*
  * Check for disabled IPv4 mapped addresses.
  */
-#if defined(_ALLBSD_SOURCE)
+#if defined(_ALLBSD_SOURCE) && !defined(IPV6_V6ONLY)
 int cannotMap4to6(JNIEnv *env, jobject iaObj);
 #endif
 
How-To-Repeat: Run jdk14 built with WITH_IPV6=YES
Comment 1 Greg Lewis freebsd_committer freebsd_triage 2006-01-31 16:35:39 UTC
Responsible Changed
From-To: freebsd-ports-bugs->glewis

I'll take this.  I'm guessing it applies to jdk15 as well.
Comment 2 Kurt Miller 2006-02-01 16:09:26 UTC
I'm confused by your patch. When WITH_IPV6=YES the jdk only
opens IPv6 sockets. The only way to communicate with ipv4 addresses
is to set net.inet6.ip6.v6only=0. 

Are you able to communicate with ipv4 addresses with your patch and when
net.inet6.ip6.v6only=1?

-Kurt
Comment 3 Hajimu UMEMOTO freebsd_committer freebsd_triage 2006-02-01 16:21:48 UTC
Hi,

>>>>> On Wed, 01 Feb 2006 11:09:26 -0500
>>>>> Kurt Miller <lists@intricatesoftware.com> said:

lists> I'm confused by your patch. When WITH_IPV6=YES the jdk only
lists> opens IPv6 sockets. The only way to communicate with ipv4 addresses
lists> is to set net.inet6.ip6.v6only=0. 

The net.inet6.ip6.v6only is system wide setting.  We have a way to
enable/disable use of an IPv4-mapped IPv6 address per socket basis,
too.  The IPV6_V6ONLY socket option is for this purpose.

lists> Are you able to communicate with ipv4 addresses with your patch and when
lists> net.inet6.ip6.v6only=1?

Yes, the aim of my patch is to make jdk14 be able to use an IPv4 with
net.inet6.ip6.v6only=1.

Sincerely,

--
Hajimu UMEMOTO @ Internet Mutual Aid Society Yokohama, Japan
ume@mahoroba.org  ume@{,jp.}FreeBSD.org
http://www.imasy.org/~ume/
Comment 4 Kurt Miller 2006-02-01 20:36:32 UTC
>lists> Are you able to communicate with ipv4 addresses with your patch and when
>lists> net.inet6.ip6.v6only=1?
>
>Yes, the aim of my patch is to make jdk14 be able to use an IPv4 with
>net.inet6.ip6.v6only=1.
>  
>

Hi,

I can't confirm clearing the IV6_ONLY socket option overrides
the system sysctl net.inet6.ip6.v6only=1 with the following
program. It works with net.inet6.ip6.v6only=0 but fails on both
5.4 and 6.0 with:

sendto: Address family not supported by protocol family

Does this program work for you with sysctl net.inet6.ip6.v6only=1?

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <sys/param.h>
#include <netdb.h>

void
buildAddr6(struct sockaddr_in6 *addr6, int address, short port) {
  char maddr[sizeof(struct in6_addr)];

  memset((char *) addr6, 0, sizeof(struct sockaddr_in6));
  memset((char *) maddr, 0, sizeof(struct in6_addr));

  addr6->sin6_family = AF_INET6;
  addr6->sin6_port = htons(port);
  addr6->sin6_len = sizeof(struct sockaddr_in6);

  if (address != INADDR_ANY) {
    maddr[10] = 0xff;
    maddr[11] = 0xff;
    maddr[12] = ((address >> 24) & 0xff);
    maddr[13] = ((address >> 16) & 0xff);
    maddr[14] = ((address >> 8) & 0xff);
    maddr[15] = (address & 0xff);
  }

  memcpy((void *)&(addr6->sin6_addr), maddr, sizeof(struct in6_addr) );
}

void
buildAddr4(struct sockaddr_in *addr4, int address, short port) {
  memset((char *) addr4, 0, sizeof(struct sockaddr_in));
  addr4->sin_family = AF_INET;
  addr4->sin_len = sizeof(struct sockaddr_in);
  addr4->sin_port = htons(port);
  addr4->sin_addr.s_addr = (uint32_t) htonl(address);
}

int
getHostAddress() {
  char hostname[MAXHOSTNAMELEN];
  struct addrinfo  hints, *res;
  int address = 0;

  if (gethostname(hostname, MAXHOSTNAMELEN) != 0)
    exit(1);

  memset(&hints, 0, sizeof(hints));
  hints.ai_flags = AI_CANONNAME;
  hints.ai_family = AF_INET;

  if(getaddrinfo(hostname, "domain", &hints, &res) != 0)
    exit(1);

  while( res != NULL ) {
    if (res->ai_family == AF_INET) {
      address = ntohl(((struct 
sockaddr_in*)(res->ai_addr))->sin_addr.s_addr);
      break;
    }
    res = res->ai_next;
  }

  return address;
}

int
main() {
  int sock1, sock2;
  int optval;
  struct sockaddr_in6 sock1Addr6, sock2Addr6;
  struct sockaddr_in sock2Addr4;
  int sock2AddrLen;
  short port1, port2;
  char sendBuf, readBuf;
  int hostAddress;

  if ((hostAddress = getHostAddress()) == 0)
    exit(1);

  buildAddr6(&sock1Addr6, 0, 0);

  if ((sock1 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
    exit(1);
  optval = 1;
  if (setsockopt(sock1, SOL_SOCKET, SO_BROADCAST, (char*) &optval, 
sizeof(optval)) != 0)
    exit(1);
  optval = 0;
  if (setsockopt(sock1, IPPROTO_IPV6, IPV6_V6ONLY, (char*) &optval, 
sizeof(optval)) != 0)
    exit(1);
  if (bind(sock1, (struct sockaddr *)&sock1Addr6, sizeof(sock1Addr6)) != 0)
    exit(1);

  buildAddr4(&sock2Addr4, 0, 0);

  if ((sock2 = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    exit(1);
  if (bind(sock2, (struct sockaddr *)&sock2Addr4, sizeof(sock2Addr4)) != 0)
    exit(1);
  sock2AddrLen = sizeof(sock2Addr4);
  if (getsockname(sock2, (struct sockaddr *)&sock2Addr4, &sock2AddrLen) 
!= 0)
    exit(1);
  buildAddr6(&sock2Addr6, hostAddress, ntohs(sock2Addr4.sin_port));

  sendBuf = 22;
  if (sendto(sock1, &sendBuf, 1, 0, (struct sockaddr *)&sock2Addr6, 
sizeof(sock2Addr6)) != 1) {
    perror("sendto");
    exit(1);
  }

  if (read(sock2, &readBuf, 1) != 1)
    exit(1);

  printf("done\n");
}
Comment 5 Hajimu UMEMOTO freebsd_committer freebsd_triage 2006-02-02 11:52:39 UTC
Hi,

>>>>> On Wed, 01 Feb 2006 15:36:32 -0500
>>>>> Kurt Miller <kurt@intricatesoftware.com> said:

kurt> I can't confirm clearing the IV6_ONLY socket option overrides
kurt> the system sysctl net.inet6.ip6.v6only=1 with the following
kurt> program. It works with net.inet6.ip6.v6only=0 but fails on both
kurt> 5.4 and 6.0 with:

kurt> sendto: Address family not supported by protocol family

kurt> Does this program work for you with sysctl net.inet6.ip6.v6only=1?

Oops, I realized that the IPV6_V6ONLY socket option didn't work
correctly for an UDP.  I've committed the fix into HEAD:

http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/netinet6/udp6_usrreq.c.diff?r1=1.55&r2=1.56

RELENG_6 and RELENG_5 are in code freeze now.  I'll do MFC to be in
time for 6.1-RELEASE and 5.5-RELEASE if re@ allows to do so.
Indeed, I made the IPV6_V6ONLY socket option work over three years
ago.  However, I had completely forget to commit the UDP part of the
change.  Thank you for letting me about it.

Sincerely,

--
Hajimu UMEMOTO @ Internet Mutual Aid Society Yokohama, Japan
ume@mahoroba.org  ume@{,jp.}FreeBSD.org
http://www.imasy.org/~ume/
Comment 6 Kurt Miller 2006-02-02 13:58:52 UTC
Hajimu UMEMOTO wrote:

>Oops, I realized that the IPV6_V6ONLY socket option didn't work
>correctly for an UDP.  I've committed the fix into HEAD:
>
>http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/netinet6/udp6_usrreq.c.diff?r1=1.55&r2=1.56
>
>RELENG_6 and RELENG_5 are in code freeze now.  I'll do MFC to be in
>time for 6.1-RELEASE and 5.5-RELEASE if re@ allows to do so.
>Indeed, I made the IPV6_V6ONLY socket option work over three years
>ago.  However, I had completely forget to commit the UDP part of the
>change.  Thank you for letting me about it.
>  
>

Cool. Initially I didn't realize that this option was intended to
override the sysctl. Thanks for clearing that up for me and fixing
the bug. So this provides us some options in the future. 

I'm wondering about the security implications of allowing
ipv4 mapped addresses. Is that something you could comment on?

For 1.5 there is another option. Sun implemented separate stack
support for windows (open two sockets v6/v4 and use as needed).
Porting windows jdk/net code to BSD is a bit of work but avoids any
possible security implications of v4 mapped addresses.

-Kurt
Comment 7 Hajimu UMEMOTO freebsd_committer freebsd_triage 2006-02-02 15:55:18 UTC
Hi,

>>>>> On Thu, 02 Feb 2006 08:58:52 -0500
>>>>> Kurt Miller <kurt@intricatesoftware.com> said:

kurt> I'm wondering about the security implications of allowing
kurt> ipv4 mapped addresses. Is that something you could comment on?

I think that the problem is having two representation of an IPv4
address; a native IPv4 address and an IPv4-mapped IPv6 address.  The
programmers, administrators and users might be confused about it,
especially they want to filter certain IPv4 address.
Further, we cannot bind to only an IPv6, except binding to the IPv6
address of the host, in the environment where an IPv4-mapped IPv6
address is always on.  It makes providing IPv6 only service hard.

Unless having the IPV6_V6ONLY socket option, we are forced to enable
an IPv4-mapped IPv6 address for whole system to run an application
that depends on an IPv4-mapped IPv6 address.  Use of an IPV6_V6ONLY
socket option makes this situation better.

kurt> For 1.5 there is another option. Sun implemented separate stack
kurt> support for windows (open two sockets v6/v4 and use as needed).
kurt> Porting windows jdk/net code to BSD is a bit of work but avoids any
kurt> possible security implications of v4 mapped addresses.

It is good news.  We should avoid use of an IPv4-mapped IPv6 address
as possible as we can.

Sincerely,

--
Hajimu UMEMOTO @ Internet Mutual Aid Society Yokohama, Japan
ume@mahoroba.org  ume@{,jp.}FreeBSD.org
http://www.imasy.org/~ume/
Comment 8 Hajimu UMEMOTO freebsd_committer freebsd_triage 2006-02-09 03:48:09 UTC
Hi,

>>>>> On Thu, 02 Feb 2006 20:52:39 +0900
>>>>> Hajimu UMEMOTO <ume@FreeBSD.org> said:

ume> RELENG_6 and RELENG_5 are in code freeze now.  I'll do MFC to be in
ume> time for 6.1-RELEASE and 5.5-RELEASE if re@ allows to do so.

I did MFC it into RELENG_6, RELENG_5 and RELENG_4.

Sincerely,

--
Hajimu UMEMOTO @ Internet Mutual Aid Society Yokohama, Japan
ume@mahoroba.org  ume@{,jp.}FreeBSD.org
http://www.imasy.org/~ume/
Comment 9 TsurutaniNaoki 2006-06-30 09:32:07 UTC
Is this issue still open ?
Patches about kernel are introduced, but patches about jdk14 (and other jdk's) are
not adopted yet...
Comment 10 dfilter service freebsd_committer freebsd_triage 2006-10-08 20:20:35 UTC
glewis      2006-10-08 19:20:28 UTC

  FreeBSD ports repository

  Added files:
    java/jdk14/files     patch-ipv6only 
  Log:
  . Add a patch to support IPv6 only operation.
    (Makefile knob to follow)
  
  PR:             92620
  Submitted by:   ume@
  
  Revision  Changes    Path
  1.1       +131 -0    ports/java/jdk14/files/patch-ipv6only (new)
_______________________________________________
cvs-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/cvs-all
To unsubscribe, send any mail to "cvs-all-unsubscribe@freebsd.org"
Comment 11 Greg Lewis freebsd_committer freebsd_triage 2006-10-08 20:23:21 UTC
State Changed
From-To: open->closed

Committed.  Thanks!  Please give it a try.