This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Patch: IP_MULTICAST_LOOP support


On Mon, 2005-01-31 at 13:03 -0700, Tom Tromey wrote:
> >>>>> "Anthony" == Anthony Green <green@redhat.com> writes:
> 
> >> http://www.linux.org/docs/ldp/howto/Multicast-HOWTO-6.html
> >> ... the 'val' argument must be an 'unsigned char'.
> 
> Anthony> "must be"?  I thought there was some flexibility here, as we
> Anthony> also pass the size of 'val' as the last argument.
> 
> Yeah, I wonder about that.  It is conceivable that the kernel just
> checks the value and if it is not '1', returns EINVAL.  Could you
> check this?  I'm ok with an actual test or with just looking at the
> kernel source.  Or I suppose finding a definitive source for the docs,
> SUS or something.

The LSB says that it must be an integer.
http://refspecs.freestandards.org/LSB_2.0.1/LSB-generic/LSB-generic.txt

"IP_MULTICAST_LOOP

    Sets a boolean flag indicating whether multicast packets originating
    locally should be looped back to the local sockets. optval is a pointer to
    an integer which contains the new flag value."

> I also wonder whether the getsockopt code for this option is correct.

No.  See attached revised patch.

> Anthony> The attached patch also enables the SO_REUSEADDR option.  I
> Anthony> think this was disabled in error..
> 
> I tracked this down to the very beginnings of our java.net, as written
> by Warren.  My random googling shows that this is probably incorrect
> though.
> 
> This part of the patch is fine as far as it goes... but could you
> also fix the getsockopt part?

Ok, see attached.

Thanks,

AG


2005-01-31  Anthony Green  <green@redhat.com>

	* gnu/java/net/natPlainDatagramSocketImplPosix.cc (getOption):
	Support IP_MULTICAST_LOOP.
	(setOption): Support IP_MULTICAST_LOOP.

	* gnu/java/net/natPlainSocketImplPosix.cc (setOption): Add
	SO_REUSEADDR support.
	(getOption): Support SO_REUSEADDR.


Index: gnu/java/net/natPlainDatagramSocketImplPosix.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/net/natPlainDatagramSocketImplPosix.cc,v
retrieving revision 1.7
diff -c -u -p -r1.7 natPlainDatagramSocketImplPosix.cc
--- gnu/java/net/natPlainDatagramSocketImplPosix.cc	17 Mar 2004 08:10:28 -0000	1.7
+++ gnu/java/net/natPlainDatagramSocketImplPosix.cc	1 Feb 2005 04:47:02 -0000
@@ -602,9 +602,27 @@ gnu::java::net::PlainDatagramSocketImpl:
         return;
 	
       case _Jv_IP_MULTICAST_LOOP_ :
-        throw new ::java::net::SocketException (
-          JvNewStringUTF ("IP_MULTICAST_LOOP: not yet implemented"));
-        return;
+	haddress = ((::java::net::InetAddress *) value)->addr;
+	len = haddress->length;
+	if (len == 4)
+	  {
+	    level = IPPROTO_IP;
+	    opname = IP_MULTICAST_LOOP;
+	  }
+#if defined (HAVE_INET6) && defined (IPV6_MULTICAST_LOOP)
+	else if (len == 16)
+	  {
+	    level = IPPROTO_IPV6;
+	    opname = IPV6_MULTICAST_LOOP;
+	  }
+#endif
+	else
+	  throw
+	    new ::java::net::SocketException (JvNewStringUTF ("invalid address length"));
+	if (::setsockopt (native_fd, level, opname, (char *) &val,
+			  val_len) != 0)
+	  goto error;
+	return;
 	
       case _Jv_IP_TOS_ :
         if (::setsockopt (native_fd, SOL_SOCKET, IP_TOS, (char *) &val,
@@ -631,6 +649,7 @@ gnu::java::net::PlainDatagramSocketImpl:
   socklen_t val_len = sizeof(val);
   union SockAddr u;
   socklen_t addrlen = sizeof(u);
+  int level, opname;
 
   switch (optID)
     {
@@ -738,8 +757,47 @@ gnu::java::net::PlainDatagramSocketImpl:
         break;
 	
       case _Jv_IP_MULTICAST_LOOP_ :
-	if (::getsockopt (native_fd, SOL_SOCKET, IP_MULTICAST_LOOP, (char *) &val,
-	    &val_len) != 0)
+	// cache the local address
+	if (localAddress == NULL)
+	  {	
+	    jbyteArray laddr;
+	    if (::getsockname (native_fd, (sockaddr*) &u, &addrlen) != 0)
+	      goto error;
+	    if (u.address.sin_family == AF_INET)
+	      {
+		laddr = JvNewByteArray (4);
+		memcpy (elements (laddr), &u.address.sin_addr, 4);
+	      }
+#ifdef HAVE_INET6
+            else if (u.address.sin_family == AF_INET6)
+	      {
+		laddr = JvNewByteArray (16);
+		memcpy (elements (laddr), &u.address6.sin6_addr, 16);
+	      }
+#endif
+	    else
+	      throw new ::java::net::SocketException (
+			      JvNewStringUTF ("invalid family"));
+	    localAddress = new ::java::net::InetAddress (laddr, NULL);
+	    
+	  }
+	if (localAddress->addr->length == 4) 
+	  {
+	    level = IPPROTO_IP;
+	    opname = IP_MULTICAST_LOOP;
+	  }
+#if defined (HAVE_INET6) && defined (IPV6_MULTICAST_LOOP)
+	else if (localAddress->addr->length == 16)
+	  {
+	    level = IPPROTO_IPV6;
+	    opname = IPV6_MULTICAST_LOOP;
+	  }
+#endif
+	else
+	  throw
+	    new ::java::net::SocketException (JvNewStringUTF ("invalid address length"));
+	if (::getsockopt (native_fd, level, opname, (char *) &val,
+			  &val_len) != 0)
 	  goto error;
 	return new ::java::lang::Boolean (val != 0);
 	
Index: gnu/java/net/natPlainSocketImplPosix.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/net/natPlainSocketImplPosix.cc,v
retrieving revision 1.10
diff -c -u -p -r1.10 natPlainSocketImplPosix.cc
--- gnu/java/net/natPlainSocketImplPosix.cc	22 Oct 2004 15:27:04 -0000	1.10
+++ gnu/java/net/natPlainSocketImplPosix.cc	1 Feb 2005 04:47:02 -0000
@@ -637,9 +637,14 @@ gnu::java::net::PlainSocketImpl::setOpti
         return;
 	
       case _Jv_SO_REUSEADDR_ :
-        throw new ::java::net::SocketException (
-          JvNewStringUTF ("SO_REUSEADDR: not valid for TCP"));
-        return;
+#if defined(SO_REUSEADDR)
+	if (::setsockopt (native_fd, SOL_SOCKET, SO_REUSEADDR, (char *) &val,
+	    val_len) != 0)
+	  goto error;
+#else
+        throw new ::java::lang::InternalError (
+          JvNewStringUTF ("SO_REUSEADDR not supported"));
+#endif 
 
       case _Jv_SO_TIMEOUT_ :
         timeout = val;
@@ -780,8 +785,14 @@ gnu::java::net::PlainSocketImpl::getOpti
       break;
 	
     case _Jv_SO_REUSEADDR_ :
-      throw new ::java::net::SocketException
-        (JvNewStringUTF ("SO_REUSEADDR: not valid for TCP"));
+#if defined(SO_REUSEADDR)
+      if (::getsockopt (native_fd, SOL_SOCKET, SO_REUSEADDR, (char *) &val,
+                        &val_len) != 0)
+        goto error;    
+#else
+        throw new ::java::lang::InternalError (
+          JvNewStringUTF ("SO_REUSEADDR not supported"));
+#endif 
       break;
 
     case _Jv_SO_TIMEOUT_ :




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]