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);
}