diff options
author | Benoit Foucher <benoit@zeroc.com> | 2017-01-20 16:52:33 +0100 |
---|---|---|
committer | Benoit Foucher <benoit@zeroc.com> | 2017-01-20 16:52:33 +0100 |
commit | 10d9e3aae20e55d9824b632e77d8f14fd67b122f (patch) | |
tree | e38f0c77e423d9c1a8a5faf4abfccdfa63a905b3 /java-compat | |
parent | java:UserException metadata for both local and remote operations (diff) | |
download | ice-10d9e3aae20e55d9824b632e77d8f14fd67b122f.tar.bz2 ice-10d9e3aae20e55d9824b632e77d8f14fd67b122f.tar.xz ice-10d9e3aae20e55d9824b632e77d8f14fd67b122f.zip |
Fixed ICE-6708 - the UDP transport now join the multicast group on all interfaces by default
Diffstat (limited to 'java-compat')
3 files changed, 121 insertions, 105 deletions
diff --git a/java-compat/src/Ice/src/main/java/IceInternal/Network.java b/java-compat/src/Ice/src/main/java/IceInternal/Network.java index 0e19cf0e0b0..7ee1da0cf58 100644 --- a/java-compat/src/Ice/src/main/java/IceInternal/Network.java +++ b/java-compat/src/Ice/src/main/java/IceInternal/Network.java @@ -250,6 +250,82 @@ public final class Network } } + public static java.net.NetworkInterface + getInterface(String intf) + { + java.net.NetworkInterface iface; + try + { + iface = java.net.NetworkInterface.getByName(intf); + if(iface != null) + { + return iface; + } + } + catch(Exception ex) + { + } + try + { + iface = java.net.NetworkInterface.getByInetAddress(java.net.InetAddress.getByName(intf)); + if(iface != null) + { + return iface; + } + } + catch(Exception ex) + { + } + throw new IllegalArgumentException("couldn't find interface `" + intf + "'"); + } + + public static void + setMcastInterface(java.nio.channels.DatagramChannel fd, String intf) + { + try + { + fd.setOption(java.net.StandardSocketOptions.IP_MULTICAST_IF, getInterface(intf)); + } + catch(Exception ex) + { + throw new Ice.SocketException(ex); + } + } + + public static void + setMcastGroup(java.nio.channels.DatagramChannel fd, java.net.InetSocketAddress group, String intf) + { + try + { + java.util.List<String> interfaces = getHostsForEndpointExpand(intf, getProtocolSupport(group), true); + if(interfaces.isEmpty()) + { + interfaces.add(intf); + } + for(String intf2 : interfaces) + { + fd.join(group.getAddress(), getInterface(intf2)); + } + } + catch(Exception ex) + { + throw new Ice.SocketException(ex); + } + } + + public static void + setMcastTtl(java.nio.channels.DatagramChannel fd, int ttl) + { + try + { + fd.setOption(java.net.StandardSocketOptions.IP_MULTICAST_TTL, ttl); + } + catch(Exception ex) + { + throw new Ice.SocketException(ex); + } + } + public static void setBlock(java.nio.channels.SelectableChannel fd, boolean block) { @@ -663,6 +739,12 @@ public final class Network return size; } + public static int + getProtocolSupport(java.net.InetSocketAddress addr) + { + return addr.getAddress().getAddress().length == 4 ? Network.EnableIPv4 : Network.EnableIPv6; + } + public static java.net.InetSocketAddress getAddressForServer(String host, int port, int protocol, boolean preferIPv6) { diff --git a/java-compat/src/Ice/src/main/java/IceInternal/UdpEndpointI.java b/java-compat/src/Ice/src/main/java/IceInternal/UdpEndpointI.java index 9d8a1f45c54..29abe1fcad1 100644 --- a/java-compat/src/Ice/src/main/java/IceInternal/UdpEndpointI.java +++ b/java-compat/src/Ice/src/main/java/IceInternal/UdpEndpointI.java @@ -159,6 +159,25 @@ final class UdpEndpointI extends IPEndpointI _connect, _connectionId, _compress); } + @Override + public void initWithOptions(java.util.ArrayList<String> args, boolean oaEndpoint) + { + super.initWithOptions(args, oaEndpoint); + + if(_mcastInterface.equals("*")) + { + if(oaEndpoint) + { + _mcastInterface = ""; + } + else + { + throw new Ice.EndpointParseException("`--interface *' not valid for proxy endpoint `" + + toString() + "'"); + } + } + } + // // Convert the endpoint to its string form // diff --git a/java-compat/src/Ice/src/main/java/IceInternal/UdpTransceiver.java b/java-compat/src/Ice/src/main/java/IceInternal/UdpTransceiver.java index 1f4899f7bce..fe6f67d295e 100644 --- a/java-compat/src/Ice/src/main/java/IceInternal/UdpTransceiver.java +++ b/java-compat/src/Ice/src/main/java/IceInternal/UdpTransceiver.java @@ -63,8 +63,7 @@ final class UdpTransceiver implements Transceiver { Network.setReuseAddress(_fd, true); _mcastAddr = _addr; - if(System.getProperty("os.name").startsWith("Windows") || - System.getProperty("java.vm.name").startsWith("OpenJDK")) + if(System.getProperty("os.name").startsWith("Windows")) { // // Windows does not allow binding to the mcast address itself @@ -73,17 +72,15 @@ final class UdpTransceiver implements Transceiver // address won't be the multicast address and the client will // therefore reject the datagram. // - int protocol = - _mcastAddr.getAddress().getAddress().length == 4 ? Network.EnableIPv4 : Network.EnableIPv6; - _addr = Network.getAddressForServer("", _port, protocol, _instance.preferIPv6()); + int protocolSupport = Network.getProtocolSupport(_mcastAddr); + _addr = Network.getAddressForServer("", _port, protocolSupport, _instance.preferIPv6()); } _addr = Network.doBind(_fd, _addr); - configureMulticast(_mcastAddr, _mcastInterface, -1); - if(_port == 0) { _mcastAddr = new java.net.InetSocketAddress(_mcastAddr.getAddress(), _addr.getPort()); } + Network.setMcastGroup(_fd, _mcastAddr, _mcastInterface); } else { @@ -285,8 +282,12 @@ final class UdpTransceiver implements Transceiver public String toDetailedString() { StringBuilder s = new StringBuilder(toString()); - java.util.List<String> intfs = - Network.getHostsForEndpointExpand(_addr.getAddress().getHostAddress(), _instance.protocolSupport(), true); + String addr = _mcastAddr != null ? _mcastInterface : _addr.getAddress().getHostAddress(); + java.util.List<String> intfs = Network.getHostsForEndpointExpand(addr, _instance.protocolSupport(), true); + if(_mcastAddr != null && intfs.isEmpty()) + { + intfs.add(_mcastInterface); + } if(!intfs.isEmpty()) { s.append("\nlocal interfaces = "); @@ -380,7 +381,14 @@ final class UdpTransceiver implements Transceiver // if(_addr.getAddress().isMulticastAddress()) { - configureMulticast(null, mcastInterface, mcastTtl); + if(mcastInterface.length() > 0) + { + Network.setMcastInterface(_fd, mcastInterface); + } + if(mcastTtl != -1) + { + Network.setMcastTtl(_fd, mcastTtl); + } } Network.doConnect(_fd, _addr, sourceAddr); _state = StateConnected; // We're connected now @@ -497,8 +505,8 @@ final class UdpTransceiver implements Transceiver if((isSnd && (!winfo.sndWarn || winfo.sndSize != sizeRequested)) || (!isSnd && (!winfo.rcvWarn || winfo.rcvSize != sizeRequested))) { - _instance.logger().warning("UDP " + direction + " buffer size: requested size of " - + sizeRequested + " adjusted to " + sizeSet); + _instance.logger().warning("UDP " + direction + " buffer size: requested size of " + + sizeRequested + " adjusted to " + sizeSet); if(isSnd) { @@ -514,99 +522,6 @@ final class UdpTransceiver implements Transceiver } } - private void configureMulticast(java.net.InetSocketAddress group, String interfaceAddr, int ttl) - { - try - { - java.net.NetworkInterface intf = null; - - if(interfaceAddr.length() != 0) - { - intf = java.net.NetworkInterface.getByName(interfaceAddr); - if(intf == null) - { - try - { - intf = java.net.NetworkInterface.getByInetAddress( - java.net.InetAddress.getByName(interfaceAddr)); - } - catch(Exception ex) - { - } - } - } - - if(group != null) - { - // - // Join multicast group. - // - if(intf != null) - { - _fd.join(group.getAddress(), intf); - } - else - { - boolean join = false; - // - // If the user doesn't specify an interface, we join to the multicast group with every - // interface that supports multicast and has a configured address with the same protocol - // as the group address protocol. - // - int protocol = group.getAddress().getAddress().length == 4 ? Network.EnableIPv4 : - Network.EnableIPv6; - - java.util.List<java.net.NetworkInterface> interfaces = - java.util.Collections.list(java.net.NetworkInterface.getNetworkInterfaces()); - for(java.net.NetworkInterface iface : interfaces) - { - boolean hasProtocolAddress = false; - java.util.List<java.net.InetAddress> addresses = - java.util.Collections.list(iface.getInetAddresses()); - for(java.net.InetAddress address : addresses) - { - if(address.getAddress().length == 4 && protocol == Network.EnableIPv4 || - address.getAddress().length != 4 && protocol == Network.EnableIPv6) - { - hasProtocolAddress = true; - break; - } - } - - if(hasProtocolAddress) - { - _fd.join(group.getAddress(), iface); - join = true; - } - } - - if(!join) - { - throw new Ice.SocketException(new IllegalArgumentException( - "There are no interfaces that are configured for the group protocol.\n" + - "Cannot join the multicast group.")); - } - } - } - else if(intf != null) - { - // - // Otherwise, set the multicast interface if specified. - // - _fd.setOption(java.net.StandardSocketOptions.IP_MULTICAST_IF, intf); - } - - if(ttl != -1) - { - _fd.setOption(java.net.StandardSocketOptions.IP_MULTICAST_TTL, ttl); - } - } - catch(Exception ex) - { - throw new Ice.SocketException(ex); - } - } - @Override protected synchronized void finalize() throws Throwable |