Hi,

I patched openjdk7. Attached you'll find the patch.
It is now possible (at least for me) to use MulticastSocket.
I know the patch is not ready for checkin, but I guess you'll get
the idea and know how to do it properly as I don't know the correct
defines to check. (The first two chunks in the patch are probably
already in HG as the patch is based on u6 code)

Basically I just replaced the MACOSX check with __FreeBSD__ and
it works now:

root@bigoli test> /usr/local/bootstrap-openjdk/bin/javac test.java
root@bigoli test> /usr/local/bootstrap-openjdk/bin/jar -cf test.jar Main.class
root@bigoli test> /usr/local/openjdk7/bin/java -classpath .:test.jar Main
network interface: name:null
interface: /10.0.1.1

Java is still not able to detect my network interface name, but this
was also not working in Diablo JRE and I don't need it. At least I'm
now getting the correct Multicast Address back (10.0.1.1 and not 0.0.0.0)

Please consider fixing this upstream.

PS: Sorry for top-post but I'm CCing FreeBSDs java@ list


Kurt Miller <k...@intricatesoftware.com> wrote:

Hi Oliver,

On 01/31/13 13:26, Oliver Lehmann wrote:
Hi,

I encountered a bug while migrating from FreeBSDs old "Diablo jre"
to openjdk-jre version 6.

I'm running a software using multicast communication and it fails
on FreeBSD when using openjdk6.

example code:

import java.io.IOException;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.SocketException;
import java.net.UnknownHostException;


class Main {
   static String hostname = new String("10.0.1.1");

   public static void main(String args[]) throws
       SocketException, UnknownHostException, IOException{
     InetAddress ia = InetAddress.getByName(hostname);
     MulticastSocket ssdpSocket = new MulticastSocket();

     ssdpSocket.setInterface(ia);

     System.out.println("network interface: " +
          ssdpSocket.getNetworkInterface());
     System.out.println("interface: " + ssdpSocket.getInterface());
   }
}


The output of the old "Diablo JRE" is:

   network interface: name:null index: -1 addresses:
   /10.0.1.1;

   interface: /10.0.1.1


The output of openJDK6 is:

   network interface: name:null
   interface: /0.0.0.0

It always returns this information.
For comparison - openjdk on Linux:

   network interface: name:eth0 (eth0)
   interface: /10.0.1.54

Oracle 7 VM on Windows:

   network interface: name:eth3 (Realtek PCIe GBE Family Controller)
   interface: /10.0.1.51

I can confirm this is a problem for bsd-port (openjdk7)
on OpenBSD too.

For me this seems to be an implementation bug of... I don't know?
PlainDatagramSocketImpl.c maybe?

I tried to debug this further, but did not succeeded to find out if
either setInterface() failed to set it correctly, or somewhere in
getInterface() an early return() happens. I tried to remotly debug
this using Eclipse, but only saw the private variables of ssdpSocket
which didn't indicated something obvious. Breakpoints inside
java.net.MulticastSocket would have helped ;)




--- ./jdk/src/solaris/native/java/net/PlainDatagramSocketImpl.c.orig	2012-08-10 19:31:31.000000000 +0200
+++ ./jdk/src/solaris/native/java/net/PlainDatagramSocketImpl.c	2013-02-01 07:50:33.000000000 +0100
@@ -23,12 +23,12 @@
  * questions.
  */
 
+#include <sys/types.h>
+#include <sys/socket.h>
 #include <errno.h>
 #include <netinet/in.h>
 #include <stdlib.h>
 #include <string.h>
-#include <sys/types.h>
-#include <sys/socket.h>
 
 #ifdef __solaris__
 #include <fcntl.h>
@@ -357,13 +357,21 @@
 #ifdef AF_INET6
         if (ipv6_available()) {
             struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)&addr;
+#ifdef __FreeBSD__
+            him6->sin6_family = AF_INET6;
+#else
             him6->sin6_family = AF_UNSPEC;
+#endif
             len = sizeof(struct sockaddr_in6);
         } else
 #endif
         {
             struct sockaddr_in *him4 = (struct sockaddr_in*)&addr;
+#ifdef __FreeBSD__
+            him4->sin_family = AF_INET;
+#else
             him4->sin_family = AF_UNSPEC;
+#endif
             len = sizeof(struct sockaddr_in);
         }
         JVM_Connect(fd, (struct sockaddr *)&addr, len);
@@ -1350,7 +1358,7 @@
          * value is an InetAddress.
          */
 #ifdef AF_INET6
-#if defined(__solaris__) || defined(MACOSX)
+#if defined(__solaris__) || defined(__FreeBSD__)
         if (ipv6_available()) {
             mcast_set_if_by_addr_v6(env, this, fd, value);
         } else {
@@ -1373,7 +1381,7 @@
          * value is a NetworkInterface.
          */
 #ifdef AF_INET6
-#if defined(__solaris__) || defined(MACOSX)
+#if defined(__solaris__) || defined(__FreeBSD__)
         if (ipv6_available()) {
             mcast_set_if_by_if_v6(env, this, fd, value);
         } else {
@@ -1456,7 +1464,7 @@
 static void setMulticastLoopbackMode(JNIEnv *env, jobject this, int fd,
                                   jint opt, jobject value) {
 #ifdef AF_INET6
-#if defined(__solaris__) || defined(MACOSX)
+#if defined(__solaris__) || defined(__FreeBSD__)
     if (ipv6_available()) {
         mcast_set_loop_v6(env, this, fd, value);
     } else {
@@ -2030,7 +2038,7 @@
     }
     /* setsockopt to be correct ttl */
 #ifdef AF_INET6
-#if defined(__solaris__) || defined(MACOSX)
+#if defined(__solaris__) || defined(__FreeBSD__)
     if (ipv6_available()) {
         setHopLimit(env, fd, ttl);
     } else {
@@ -2419,7 +2427,7 @@
                 }
             }
 #endif
-#ifdef MACOSX
+#ifdef __FreeBSD__
             if (family == AF_INET6 && index == 0) {
                 index = getDefaultScopeID(env);
             }


Reply via email to