[jboss-cvs] JBossAS SVN: r79684 - trunk/cluster/src/main/org/jboss/ha/jndi.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Fri Oct 17 21:01:54 EDT 2008


Author: bstansberry at jboss.com
Date: 2008-10-17 21:01:54 -0400 (Fri, 17 Oct 2008)
New Revision: 79684

Modified:
   trunk/cluster/src/main/org/jboss/ha/jndi/DetachedHANamingService.java
Log:
[JBAS-6080] On Linux, pass socket address to MulticastSocket constructor

Modified: trunk/cluster/src/main/org/jboss/ha/jndi/DetachedHANamingService.java
===================================================================
--- trunk/cluster/src/main/org/jboss/ha/jndi/DetachedHANamingService.java	2008-10-18 00:54:23 UTC (rev 79683)
+++ trunk/cluster/src/main/org/jboss/ha/jndi/DetachedHANamingService.java	2008-10-18 01:01:54 UTC (rev 79684)
@@ -28,12 +28,17 @@
 import java.lang.reflect.Method;
 import java.lang.reflect.UndeclaredThrowableException;
 import java.net.DatagramPacket;
+import java.net.Inet4Address;
 import java.net.InetAddress;
+import java.net.InetSocketAddress;
 import java.net.MulticastSocket;
 import java.net.ServerSocket;
 import java.net.Socket;
+import java.net.SocketAddress;
 import java.net.UnknownHostException;
 import java.rmi.MarshalledObject;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
@@ -41,6 +46,7 @@
 import javax.management.ObjectName;
 import javax.net.ServerSocketFactory;
 
+import org.apache.commons.logging.Log;
 import org.jboss.ha.framework.interfaces.HAPartition;
 import org.jboss.ha.jndi.spi.DistributedTreeManager;
 import org.jboss.invocation.Invocation;
@@ -50,6 +56,7 @@
 import org.jboss.util.threadpool.BasicThreadPool;
 import org.jboss.util.threadpool.BasicThreadPoolMBean;
 import org.jboss.util.threadpool.ThreadPool;
+import org.jgroups.util.Util;
 import org.jnp.interfaces.Naming;
 import org.jnp.interfaces.NamingContext;
 
@@ -527,21 +534,40 @@
       public void start() throws Exception
       {
          this.stopping = false;
+         
+         // Set up the multicast socket on which we listen for discovery requests
+         
+         this.group = InetAddress.getByName(DetachedHANamingService.this.adGroupAddress);
+         
+         // On Linux, we avoid cross-talk problem by binding the MulticastSocket
+         // to the multicast address. See https://jira.jboss.org/jira/browse/JGRP-777
+         if(checkForPresence("os.name", "linux"))
+         {             
+            this.socket = createMulticastSocket(group, DetachedHANamingService.this.adGroupPort);
+         }
+         else
+         {
+            this.socket = new MulticastSocket(DetachedHANamingService.this.adGroupPort);
+         }
+         
+         // If there is a valid bind address, set the socket interface to it         
          // Use the jndi bind address if there is no discovery address
          if (DetachedHANamingService.this.discoveryBindAddress == null)
          {
             DetachedHANamingService.this.discoveryBindAddress = DetachedHANamingService.this.bindAddress;
          }
-         this.socket = new MulticastSocket(DetachedHANamingService.this.adGroupPort);
-         // If there is a bind address valid, set the socket interface to it
-         if (DetachedHANamingService.this.discoveryBindAddress != null && DetachedHANamingService.this.discoveryBindAddress.isAnyLocalAddress() == false)
+         
+         if (DetachedHANamingService.this.discoveryBindAddress != null 
+               && DetachedHANamingService.this.discoveryBindAddress.isAnyLocalAddress() == false)
          {
             this.socket.setInterface(DetachedHANamingService.this.discoveryBindAddress);
          }
+         
          this.socket.setTimeToLive(DetachedHANamingService.this.autoDiscoveryTTL);
-         this.group = InetAddress.getByName(DetachedHANamingService.this.adGroupAddress);
          this.socket.joinGroup(this.group);
 
+         
+         // Determine the hostname:port string we will return to discovery requests
          String address = DetachedHANamingService.this.getBindAddress();
          /* An INADDR_ANY (0.0.0.0 || null) address is useless as the value
             sent to a remote client so check for this and use the local host
@@ -639,6 +665,65 @@
          this.receiverStopped = true;
          this.log.debug("Discovery request thread end");
       }
+
+      private boolean checkForPresence(final String key, String value)
+      {
+         try
+         {
+            String tmp = null;
+            if (System.getSecurityManager() == null)
+            {
+               tmp = System.getProperty(key);
+            }
+            else
+            {
+               tmp = (String) AccessController.doPrivileged(new PrivilegedAction()
+                  {
+                     public Object run()
+                     {
+                        return System.getProperty(key);
+                     }
+   
+                  });
+            }
+
+            return tmp != null && tmp.trim().toLowerCase().startsWith(value);
+         }
+         catch (Throwable t)
+         {
+            return false;
+         }
+      }
+      
+      private MulticastSocket createMulticastSocket(InetAddress mcast_addr, int port) throws IOException 
+      {
+        if(mcast_addr != null && !mcast_addr.isMulticastAddress()) {
+            log.warn("mcast_addr (" + mcast_addr + ") is not a multicast address, will be ignored");
+            return new MulticastSocket(port);
+        }
+
+        SocketAddress saddr=new InetSocketAddress(mcast_addr, port);
+        MulticastSocket retval=null;
+
+        try {
+            retval=new MulticastSocket(saddr);
+        }
+        catch(IOException ex) {
+            StringBuilder sb=new StringBuilder();
+             String type=mcast_addr != null ? mcast_addr instanceof Inet4Address? "IPv4" : "IPv6" : "n/a";
+             sb.append("could not bind to " + mcast_addr + " (" + type + " address)");
+             sb.append("; make sure your mcast_addr is of the same type as the IP stack (IPv4 or IPv6).");
+             sb.append("\nWill ignore mcast_addr, but this may lead to cross talking " +
+                     "(see http://www.jboss.com/wiki/Edit.jsp?page=CrossTalking for details). ");
+             sb.append("\nException was: " + ex);
+             log.warn(sb);
+        }
+        if(retval == null)
+        {
+            retval=new MulticastSocket(port);
+        }
+        return retval;
+    }
    }
 
    /**




More information about the jboss-cvs-commits mailing list