Author: andygumbrecht
Date: Thu Jun 28 10:40:35 2012
New Revision: 1354908

URL: http://svn.apache.org/viewvc?rev=1354908&view=rev
Log:
Fix multipulse client, was not observing group if not a wildcard - Doh!
Enhanced multipulse to only respond if at least one service is public - A 
service may be published on localhost, so remote clients should not be able to 
see it.

Modified:
    
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonContainer.java
    
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/MulticastPulseClient.java
    
openejb/trunk/openejb/server/openejb-multicast/src/main/java/org/apache/openejb/server/discovery/MulticastPulseAgent.java

Modified: 
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonContainer.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonContainer.java?rev=1354908&r1=1354907&r2=1354908&view=diff
==============================================================================
--- 
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonContainer.java
 (original)
+++ 
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonContainer.java
 Thu Jun 28 10:40:35 2012
@@ -207,7 +207,7 @@ public class SingletonContainer implemen
         BeanContext beanContext = callContext.getBeanContext();
                
         Duration accessTimeout = getAccessTimeout(beanContext, runMethod);
-        boolean read = beanContext.getConcurrencyAttribute(runMethod) == 
javax.ejb.LockType.READ;
+        boolean read = 
javax.ejb.LockType.READ.equals(beanContext.getConcurrencyAttribute(runMethod));
         
         final Lock lock = aquireLock(read, accessTimeout, instance, runMethod);
 

Modified: 
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/MulticastPulseClient.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/MulticastPulseClient.java?rev=1354908&r1=1354907&r2=1354908&view=diff
==============================================================================
--- 
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/MulticastPulseClient.java
 (original)
+++ 
openejb/trunk/openejb/server/openejb-client/src/main/java/org/apache/openejb/client/MulticastPulseClient.java
 Thu Jun 28 10:40:35 2012
@@ -108,6 +108,22 @@ public class MulticastPulseClient extend
             timeout = 50;
         }
 
+        if (null == forGroup || forGroup.isEmpty()) {
+            throw new Exception("Specify a valid group or *");
+        }
+
+        if (null == schemes || schemes.isEmpty()) {
+            throw new Exception("Specify at least one scheme, 'ejbd' for 
example");
+        }
+
+        if (null == host || host.isEmpty()) {
+            throw new Exception("Specify a valid host name");
+        }
+
+        if (port < 1 || port > 65535) {
+            throw new Exception("Specify a valid port between 1 and 65535");
+        }
+
         final InetAddress ia;
 
         try {
@@ -179,6 +195,7 @@ public class MulticastPulseClient extend
                             if (len > 2048) {
                                 len = 2048;
                             }
+
                             String s = new String(response.getData(), 0, len);
 
                             if (s.startsWith(MulticastPulseClient.SERVER)) {
@@ -187,31 +204,43 @@ public class MulticastPulseClient extend
                                 final String group = s.substring(0, 
s.indexOf(':'));
                                 s = s.substring(group.length() + 1);
 
+                                if (!"*".equals(forGroup) && 
!forGroup.equals(group)) {
+                                    continue;
+                                }
+
                                 final String services = s.substring(0, 
s.indexOf('|'));
                                 s = s.substring(services.length() + 1);
 
-                                final String[] service = services.split("\\|");
+                                final String[] serviceList = 
services.split("\\|");
                                 final String[] hosts = s.split(",");
 
-                                for (String svc : service) {
+                                for (String svc : serviceList) {
 
                                     if (EMPTY.equals(svc)) {
                                         continue;
                                     }
 
-                                    final URI test;
+                                    final URI serviceUri;
                                     try {
-                                        test = URI.create(svc);
+                                        serviceUri = URI.create(svc);
                                     } catch (Throwable e) {
                                         continue;
                                     }
 
-                                    if (schemes.contains(test.getScheme())) {
+                                    if 
(schemes.contains(serviceUri.getScheme())) {
 
                                         //Just because multicast was received 
on this host is does not mean the service is on the same
                                         //We can however use this to identify 
an individual machine and group
                                         final String serverHost = 
((InetSocketAddress) response.getSocketAddress()).getAddress().getHostAddress();
 
+                                        final String serviceHost = 
serviceUri.getHost();
+                                        if 
(MulticastPulseClient.isLocalAddress(serviceHost, false)) {
+                                            if 
(!MulticastPulseClient.isLocalAddress(serverHost, false)) {
+                                                //A local service is only 
available to a local clients
+                                                continue;
+                                            }
+                                        }
+
                                         svc = ("mp-" + serverHost + ":" + 
group + ":" + svc);
 
                                         try {
@@ -269,12 +298,41 @@ public class MulticastPulseClient extend
         final MulticastSocket ms = MulticastPulseClient.getSocket(ia, port);
         ms.send(request);
 
-        //Wait for thread to die
+        //Wait for thread to complete
         t.join();
 
         return set;
     }
 
+    /**
+     * Is the provided host a local host
+     *
+     * @param host            The host to test
+     * @param wildcardIsLocal Should 0.0.0.0 or [::] be deemed as local
+     * @return True is the host is a local host else false
+     */
+    public static boolean isLocalAddress(final String host, final boolean 
wildcardIsLocal) {
+
+        final InetAddress addr;
+        try {
+            addr = InetAddress.getByName(host);
+        } catch (UnknownHostException e) {
+            return false;
+        }
+
+        // Check if the address is a valid special local or loop back
+        if ((wildcardIsLocal && addr.isAnyLocalAddress()) || 
addr.isLoopbackAddress()) {
+            return true;
+        }
+
+        // Check if the address is defined on any local interface
+        try {
+            return NetworkInterface.getByInetAddress(addr) != null;
+        } catch (SocketException e) {
+            return false;
+        }
+    }
+
     private static String ipFormat(final String h) throws UnknownHostException 
{
 
         final InetAddress ia = Inet6Address.getByName(h);
@@ -385,7 +443,7 @@ public class MulticastPulseClient extend
                     if (uriSet != null && uriSet.size() > 0) {
                         for (URI uri : uriSet) {
 
-                            final String serverhost = uri.getScheme();
+                            final String server = 
uri.getScheme().replace("mp-", "");
                             uri = URI.create(uri.getSchemeSpecificPart());
 
                             final String group = uri.getScheme();
@@ -393,6 +451,12 @@ public class MulticastPulseClient extend
 
                             final String host = uri.getHost();
                             final int port = uri.getPort();
+
+                            if (MulticastPulseClient.isLocalAddress(host, 
false) && !MulticastPulseClient.isLocalAddress(server, false)) {
+                                System.out.println(server + ":" + group + " - 
" + uri.toASCIIString() + " is not a local service");
+                                continue;
+                            }
+
                             boolean b = false;
                             final Socket s = new Socket();
                             try {
@@ -408,7 +472,7 @@ public class MulticastPulseClient extend
                                 }
                             }
 
-                            System.out.println("ServerHost: " + serverhost + " 
- Group: " + group + " - Service: " + uri.toASCIIString() + " is reachable: " + 
b);
+                            System.out.println("ServerHost: " + server + " - 
Group: " + group + " - Service: " + uri.toASCIIString() + " is reachable: " + 
b);
                         }
                     } else {
                         System.out.println("Did not discover any URIs to 
test");

Modified: 
openejb/trunk/openejb/server/openejb-multicast/src/main/java/org/apache/openejb/server/discovery/MulticastPulseAgent.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb/server/openejb-multicast/src/main/java/org/apache/openejb/server/discovery/MulticastPulseAgent.java?rev=1354908&r1=1354907&r2=1354908&view=diff
==============================================================================
--- 
openejb/trunk/openejb/server/openejb-multicast/src/main/java/org/apache/openejb/server/discovery/MulticastPulseAgent.java
 (original)
+++ 
openejb/trunk/openejb/server/openejb-multicast/src/main/java/org/apache/openejb/server/discovery/MulticastPulseAgent.java
 Thu Jun 28 10:40:35 2012
@@ -58,6 +58,7 @@ public class MulticastPulseAgent impleme
     private int port = 6142;
     private DatagramPacket response = null;
     private DiscoveryListener listener = null;
+    private boolean loopbackOnly = true;
 
     /**
      * This agent listens for a client pulse on a defined multicast channel.
@@ -85,6 +86,15 @@ public class MulticastPulseAgent impleme
     }
 
     private void buildPacket() throws SocketException {
+
+        this.loopbackOnly = true;
+        for (final URI uri : uriSet) {
+            if (!isLoopback(uri.getHost())) {
+                this.loopbackOnly = false;
+                break;
+            }
+        }
+
         final String hosts = getHosts();
         final StringBuilder sb = new StringBuilder(SERVER);
         sb.append(this.group);
@@ -155,7 +165,7 @@ public class MulticastPulseAgent impleme
 
     private void fireEvent(final URI uri, final boolean add) {
         if (null != this.listener) {
-            this.executor.execute(new Runnable() {
+            executor.execute(new Runnable() {
                 @Override
                 public void run() {
                     if (add) {
@@ -195,12 +205,21 @@ public class MulticastPulseAgent impleme
 
                                     s = (s.replace(CLIENT, ""));
 
+                                    final String client = sa.toString();
+                                    if (MulticastPulseAgent.this.loopbackOnly) 
{
+                                        //We only have local services, so make 
sure the request is from a local source else ignore it
+                                        if 
(!MulticastPulseAgent.isLocalAddress(client, false)) {
+                                            log.debug(String.format("Ignoring 
client %1$s pulse request for group: %2$s - No remote services available", 
client, s));
+                                            return;
+                                        }
+                                    }
+
                                     if 
(MulticastPulseAgent.this.group.equals(s) || "*".equals(s)) {
 
-                                        log.debug(String.format("Client %1$s 
requested a pulse for group: %2$s", sa.toString(), s));
+                                        log.debug(String.format("Answering 
client %1$s pulse request for group: %2$s", client, s));
                                         
ms.send(MulticastPulseAgent.this.response);
                                     } else {
-                                        log.debug(String.format("Ignoring 
client %1$s requested pulse for group: %2$s", sa.toString(), s));
+                                        log.debug(String.format("Ignoring 
client %1$s pulse request for group: %2$s", client, s));
                                     }
                                 }
                             }
@@ -320,6 +339,47 @@ public class MulticastPulseAgent impleme
         return ms;
     }
 
+    public static boolean isLoopback(final String host) {
+
+        final InetAddress addr;
+        try {
+            addr = InetAddress.getByName(host);
+        } catch (UnknownHostException e) {
+            return false;
+        }
+
+        return addr.isLoopbackAddress();
+    }
+
+    /**
+     * Is the provided host a local host
+     *
+     * @param host            The host to test
+     * @param wildcardIsLocal Should 0.0.0.0 or [::] be deemed as local
+     * @return True is the host is a local host else false
+     */
+    public static boolean isLocalAddress(final String host, final boolean 
wildcardIsLocal) {
+
+        final InetAddress addr;
+        try {
+            addr = InetAddress.getByName(host);
+        } catch (UnknownHostException e) {
+            return false;
+        }
+
+        // Check if the address is a valid special local or loop back
+        if ((wildcardIsLocal && addr.isAnyLocalAddress()) || 
addr.isLoopbackAddress()) {
+            return true;
+        }
+
+        // Check if the address is defined on any interface
+        try {
+            return NetworkInterface.getByInetAddress(addr) != null;
+        } catch (SocketException e) {
+            return false;
+        }
+    }
+
     private static String getHosts() {
 
         final Set<String> hosts = new HashSet<String>();


Reply via email to