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
Responsible Changed From-To: freebsd-ports-bugs->glewis I'll take this. I'm guessing it applies to jdk15 as well.
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
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/
>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"); }
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/
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
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/
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/
Is this issue still open ? Patches about kernel are introduced, but patches about jdk14 (and other jdk's) are not adopted yet...
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"
State Changed From-To: open->closed Committed. Thanks! Please give it a try.