You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by tv...@apache.org on 2020/04/12 17:06:18 UTC
[commons-jcs] 02/03: Better handling of multicast on multihomed
machines
This is an automated email from the ASF dual-hosted git repository.
tv pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-jcs.git
commit f4080fe78f15606df4f13bf2b9dbf893a7e8cb17
Author: Thomas Vandahl <tv...@apache.org>
AuthorDate: Sun Apr 12 19:05:00 2020 +0200
Better handling of multicast on multihomed machines
---
.../jcs/utils/discovery/UDPDiscoveryReceiver.java | 12 ++++-
.../apache/commons/jcs/utils/net/HostNameUtil.java | 55 ++++++++++++++++++++--
.../jcs/utils/discovery/UDPDiscoveryUnitTest.java | 6 +--
3 files changed, 65 insertions(+), 8 deletions(-)
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/utils/discovery/UDPDiscoveryReceiver.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/utils/discovery/UDPDiscoveryReceiver.java
index 2fbc2eb..0438ee3 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/utils/discovery/UDPDiscoveryReceiver.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/utils/discovery/UDPDiscoveryReceiver.java
@@ -25,6 +25,7 @@ import java.io.ObjectInputStream;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
+import java.net.NetworkInterface;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.atomic.AtomicInteger;
@@ -34,6 +35,7 @@ import org.apache.commons.jcs.io.ObjectInputStreamClassLoaderAware;
import org.apache.commons.jcs.log.Log;
import org.apache.commons.jcs.log.LogManager;
import org.apache.commons.jcs.utils.discovery.UDPDiscoveryMessage.BroadcastType;
+import org.apache.commons.jcs.utils.net.HostNameUtil;
import org.apache.commons.jcs.utils.threadpool.PoolConfiguration;
import org.apache.commons.jcs.utils.threadpool.PoolConfiguration.WhenBlockedPolicy;
import org.apache.commons.jcs.utils.threadpool.ThreadPoolManager;
@@ -117,11 +119,17 @@ public class UDPDiscoveryReceiver
try
{
mSocket = new MulticastSocket( multicastPort );
+ InetAddress multicastAddress = InetAddress.getByName( multicastAddressString );
if (log.isInfoEnabled())
{
- log.info( "Joining Group: [{0}]", InetAddress.getByName( multicastAddressString ) );
+ log.info( "Joining Group: [{0}]", multicastAddress );
}
- mSocket.joinGroup( InetAddress.getByName( multicastAddressString ) );
+ NetworkInterface multicastInterface = HostNameUtil.getMulticastNetworkInterface();
+ if (multicastInterface != null)
+ {
+ mSocket.setNetworkInterface(multicastInterface);
+ }
+ mSocket.joinGroup( multicastAddress );
}
catch ( IOException e )
{
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/utils/net/HostNameUtil.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/utils/net/HostNameUtil.java
index 4e96e43..2c3bce6 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/utils/net/HostNameUtil.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/utils/net/HostNameUtil.java
@@ -1,12 +1,30 @@
package org.apache.commons.jcs.utils.net;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
import java.net.InetAddress;
import java.net.NetworkInterface;
+import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Enumeration;
-
/*
- * Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
@@ -135,7 +153,7 @@ public class HostNameUtil
}
return jdkSuppliedAddress;
}
- catch ( Exception e )
+ catch ( SocketException e )
{
UnknownHostException unknownHostException = new UnknownHostException( "Failed to determine LAN address: "
+ e );
@@ -143,4 +161,35 @@ public class HostNameUtil
throw unknownHostException;
}
}
+
+ /**
+ * On systems with multiple network interfaces and mixed IPv6/IPv4 get a valid network
+ * interface for binding to multicast
+ *
+ * @return a network interface suitable for multicast
+ * @throws SocketException if a problem occurs while reading the network interfaces
+ */
+ public static NetworkInterface getMulticastNetworkInterface() throws SocketException
+ {
+ Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
+ while (networkInterfaces.hasMoreElements())
+ {
+ NetworkInterface networkInterface = networkInterfaces.nextElement();
+ Enumeration<InetAddress> addressesFromNetworkInterface = networkInterface.getInetAddresses();
+ while (addressesFromNetworkInterface.hasMoreElements())
+ {
+ InetAddress inetAddress = addressesFromNetworkInterface.nextElement();
+ if (inetAddress.isSiteLocalAddress()
+ && !inetAddress.isAnyLocalAddress()
+ && !inetAddress.isLinkLocalAddress()
+ && !inetAddress.isLoopbackAddress()
+ && !inetAddress.isMulticastAddress())
+ {
+ return networkInterface;
+ }
+ }
+ }
+
+ return null;
+ }
}
diff --git a/commons-jcs-core/src/test/java/org/apache/commons/jcs/utils/discovery/UDPDiscoveryUnitTest.java b/commons-jcs-core/src/test/java/org/apache/commons/jcs/utils/discovery/UDPDiscoveryUnitTest.java
index 97af7bf..6a83885 100644
--- a/commons-jcs-core/src/test/java/org/apache/commons/jcs/utils/discovery/UDPDiscoveryUnitTest.java
+++ b/commons-jcs-core/src/test/java/org/apache/commons/jcs/utils/discovery/UDPDiscoveryUnitTest.java
@@ -21,10 +21,10 @@ package org.apache.commons.jcs.utils.discovery;
import java.util.ArrayList;
-import junit.framework.TestCase;
-
import org.apache.commons.jcs.utils.timing.SleepUtil;
+import junit.framework.TestCase;
+
/**
* Unit tests for discovery
*/
@@ -39,7 +39,7 @@ public class UDPDiscoveryUnitTest
throws Exception
{
UDPDiscoveryAttributes attributes = new UDPDiscoveryAttributes();
- attributes.setUdpDiscoveryAddr( "228.5.6.7" );
+ attributes.setUdpDiscoveryAddr( /*"FF7E:230::1234"*/ "228.5.6.7" );
attributes.setUdpDiscoveryPort( 6789 );
attributes.setServicePort( 1000 );