This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/main by this push: new 3cdbd46bcf Handle inversion of meaning of StandardSocketOptions.IP_MULTICAST_LOOP 3cdbd46bcf is described below commit 3cdbd46bcfc547eaf954cb12475f2da69f709557 Author: Mark Thomas <ma...@apache.org> AuthorDate: Thu Jan 12 23:18:30 2023 +0000 Handle inversion of meaning of StandardSocketOptions.IP_MULTICAST_LOOP Prior to Java 14 a value of true means loopback is disabled Java 14 onwards a value of true means loopback is enabled --- .../tribes/membership/McastServiceImpl.java | 4 +- .../apache/catalina/tribes/util/Jre14Compat.java | 61 ++++++++++++++++++++++ .../org/apache/catalina/tribes/util/JreCompat.java | 57 ++++++++++++++++++++ .../catalina/tribes/util/LocalStrings.properties | 2 + .../apache/catalina/tribes/TesterMulticast.java | 7 +-- 5 files changed, 126 insertions(+), 5 deletions(-) diff --git a/java/org/apache/catalina/tribes/membership/McastServiceImpl.java b/java/org/apache/catalina/tribes/membership/McastServiceImpl.java index 1fac0a4207..c0d79c049e 100644 --- a/java/org/apache/catalina/tribes/membership/McastServiceImpl.java +++ b/java/org/apache/catalina/tribes/membership/McastServiceImpl.java @@ -25,7 +25,6 @@ import java.net.InetSocketAddress; import java.net.MulticastSocket; import java.net.NetworkInterface; import java.net.SocketTimeoutException; -import java.net.StandardSocketOptions; import java.util.Arrays; import java.util.concurrent.atomic.AtomicBoolean; @@ -35,6 +34,7 @@ import org.apache.catalina.tribes.MembershipListener; import org.apache.catalina.tribes.MessageListener; import org.apache.catalina.tribes.io.ChannelData; import org.apache.catalina.tribes.io.XByteBuffer; +import org.apache.catalina.tribes.util.JreCompat; import org.apache.catalina.tribes.util.StringManager; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; @@ -220,7 +220,7 @@ public class McastServiceImpl extends MembershipProviderBase { socket = new MulticastSocket(port); } // Hint if we want disable loop back(local machine) messages - socket.setOption(StandardSocketOptions.IP_MULTICAST_LOOP, Boolean.valueOf(!localLoopbackDisabled)); + JreCompat.getInstance().setSocketoptionIpMulticastLoop(socket, !localLoopbackDisabled); if (mcastBindAddress != null) { if(log.isInfoEnabled()) { log.info(sm.getString("mcastServiceImpl.setInterface", mcastBindAddress)); diff --git a/java/org/apache/catalina/tribes/util/Jre14Compat.java b/java/org/apache/catalina/tribes/util/Jre14Compat.java new file mode 100644 index 0000000000..1fb58a0a28 --- /dev/null +++ b/java/org/apache/catalina/tribes/util/Jre14Compat.java @@ -0,0 +1,61 @@ +/* + * 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. + */ +package org.apache.catalina.tribes.util; + +import java.io.IOException; +import java.net.MulticastSocket; +import java.net.StandardSocketOptions; + +import org.apache.juli.logging.Log; +import org.apache.juli.logging.LogFactory; + +public class Jre14Compat extends JreCompat { + + private static final Log log = LogFactory.getLog(Jre14Compat.class); + private static final StringManager sm = StringManager.getManager(Jre14Compat.class); + + private static final boolean supported; + + static { + // Don't need any Java 19 specific classes (yet) so just test for one of + // the new ones for now. + Class<?> c1 = null; + try { + c1 = Class.forName("java.io.Serial"); + } catch (ClassNotFoundException cnfe) { + // Must be pre-Java 16 + log.debug(sm.getString("jre14Compat.javaPre14"), cnfe); + } + + supported = (c1 != null); + } + + static boolean isSupported() { + return supported; + } + + + @Override + public void setSocketoptionIpMulticastLoop(MulticastSocket socket, boolean enabled) throws IOException { + /* + * Java < 14, a value of true means loopback is disabled. Java 14+ a + * value of true means loopback is enabled. + */ + socket.setOption(StandardSocketOptions.IP_MULTICAST_LOOP, Boolean.valueOf(enabled)); + } + +} diff --git a/java/org/apache/catalina/tribes/util/JreCompat.java b/java/org/apache/catalina/tribes/util/JreCompat.java new file mode 100644 index 0000000000..2374ed1e2f --- /dev/null +++ b/java/org/apache/catalina/tribes/util/JreCompat.java @@ -0,0 +1,57 @@ +/* + * 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. + */ +package org.apache.catalina.tribes.util; + +import java.io.IOException; +import java.net.MulticastSocket; +import java.net.StandardSocketOptions; + +/** + * This is the base implementation class for JRE compatibility and provides an + * implementation based on Java 11. Sub-classes may extend this class and provide + * alternative implementations for later JRE versions + */ +public class JreCompat { + + private static final JreCompat instance; + + static { + // This is Tomcat 11.0.x with a minimum Java version of Java 11. + // Look for the highest supported JVM first + if (Jre14Compat.isSupported()) { + instance = new Jre14Compat(); + } else { + instance = new JreCompat(); + } + } + + + public static JreCompat getInstance() { + return instance; + } + + + // Java 11 implementations of Java 14 methods + + public void setSocketoptionIpMulticastLoop(MulticastSocket socket, boolean enabled) throws IOException { + /* + * Java < 14, a value of true means loopback is disabled. Java 14+ a + * value of true means loopback is enabled. + */ + socket.setOption(StandardSocketOptions.IP_MULTICAST_LOOP, Boolean.valueOf(!enabled)); + } +} diff --git a/java/org/apache/catalina/tribes/util/LocalStrings.properties b/java/org/apache/catalina/tribes/util/LocalStrings.properties index 4238fab4ac..bbfb77abc3 100644 --- a/java/org/apache/catalina/tribes/util/LocalStrings.properties +++ b/java/org/apache/catalina/tribes/util/LocalStrings.properties @@ -21,5 +21,7 @@ arrays.srcoffset.outOfBounds=srcoffset is out of bounds. executorFactory.not.running=Executor not running, can't force a command into the queues executorFactory.queue.full=Queue capacity is full. +jre14Compat.javaPre14=Class not found so assuming code is running on a pre-Java 14 JVM + uuidGenerator.createRandom=Creation of SecureRandom instance for UUID generation using [{0}] took [{1}] milliseconds. uuidGenerator.unable.fit=Unable to fit [{0}] bytes into the array. length:[{1}] required length:[{2}] diff --git a/test/org/apache/catalina/tribes/TesterMulticast.java b/test/org/apache/catalina/tribes/TesterMulticast.java index 10bb48bbb2..c0f1c95874 100644 --- a/test/org/apache/catalina/tribes/TesterMulticast.java +++ b/test/org/apache/catalina/tribes/TesterMulticast.java @@ -20,9 +20,10 @@ import java.net.DatagramPacket; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.MulticastSocket; -import java.net.StandardSocketOptions; import java.net.UnknownHostException; +import org.apache.catalina.tribes.util.JreCompat; + /** * A simple multicast test that replicates the core elements of Tomcat's * multicast membership. If this works then multicast membership should work. @@ -82,7 +83,7 @@ public class TesterMulticast { @Override public void run() { try (MulticastSocket s = new MulticastSocket(PORT)) { - s.setOption(StandardSocketOptions.IP_MULTICAST_LOOP, Boolean.TRUE); + JreCompat.getInstance().setSocketoptionIpMulticastLoop(s, true); s.joinGroup(new InetSocketAddress(INET_ADDRESS, 0), null); DatagramPacket p = new DatagramPacket(new byte[4], 4); p.setAddress(INET_ADDRESS); @@ -109,7 +110,7 @@ public class TesterMulticast { @Override public void run() { try (MulticastSocket s = new MulticastSocket(PORT)) { - s.setOption(StandardSocketOptions.IP_MULTICAST_LOOP, Boolean.TRUE); + JreCompat.getInstance().setSocketoptionIpMulticastLoop(s, true); s.joinGroup(new InetSocketAddress(INET_ADDRESS, 0), null); DatagramPacket p = new DatagramPacket(new byte[4], 4); p.setAddress(INET_ADDRESS); --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org