summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xcpp/src/Ice/Network.cpp95
-rwxr-xr-xcpp/src/Ice/Network.h1
-rwxr-xr-xcpp/src/Ice/UdpTransceiver.cpp11
-rw-r--r--csharp/src/Ice/Network.cs115
-rw-r--r--csharp/src/Ice/UdpTransceiver.cs12
-rw-r--r--java-compat/src/Ice/src/main/java/IceInternal/Network.java82
-rw-r--r--java-compat/src/Ice/src/main/java/IceInternal/UdpTransceiver.java12
-rw-r--r--java/src/Ice/src/main/java/com/zeroc/IceInternal/Network.java82
-rw-r--r--java/src/Ice/src/main/java/com/zeroc/IceInternal/UdpTransceiver.java12
9 files changed, 292 insertions, 130 deletions
diff --git a/cpp/src/Ice/Network.cpp b/cpp/src/Ice/Network.cpp
index e98aa790f22..10c4739cb72 100755
--- a/cpp/src/Ice/Network.cpp
+++ b/cpp/src/Ice/Network.cpp
@@ -513,31 +513,45 @@ isWildcard(const string& host, ProtocolSupport protocol, bool& ipv4)
}
int
-getInterfaceIndex(const string& name)
+getInterfaceIndex(const string& intf)
{
- if(name.empty())
+ if(intf.empty())
{
return 0;
}
- int index = -1;
+ string name;
+ bool isAddr;
+ in6_addr addr;
+ string::size_type pos = intf.find("%");
+ if(pos != string::npos)
+ {
+ //
+ // If it's a link-local address, use the zone indice.
+ //
+ isAddr = false;
+ name = intf.substr(pos + 1);
+ }
+ else
+ {
+ //
+ // Then check if it's an IPv6 address. If it's an address we'll
+ // look for the interface index by address.
+ //
+ isAddr = inet_pton(AF_INET6, intf.c_str(), &addr) > 0;
+ name = intf;
+ }
//
- // First check if index
+ // Check if index
//
+ int index = -1;
istringstream p(name);
if((p >> index) && p.eof())
{
return index;
}
- //
- // Then check if it's an IPv6 address. If it's an address we'll
- // look for the interface index by address.
- //
- in6_addr addr;
- bool isAddr = inet_pton(AF_INET6, name.c_str(), &addr) > 0;
-
#ifdef _WIN32
IP_ADAPTER_ADDRESSES addrs;
ULONG buflen = 0;
@@ -1627,8 +1641,7 @@ IceInternal::getHostsForEndpointExpand(const string& host, ProtocolSupport proto
HostName^ h = it->Current;
if(h->IPInformation != nullptr && h->IPInformation->NetworkAdapter != nullptr)
{
- hosts.push_back(wstringToString(h->CanonicalName->Data(),
- getProcessStringConverter()));
+ hosts.push_back(wstringToString(h->CanonicalName->Data(), getProcessStringConverter()));
}
}
if(includeLoopback)
@@ -1645,6 +1658,18 @@ IceInternal::getHostsForEndpointExpand(const string& host, ProtocolSupport proto
}
return hosts;
}
+
+vector<string>
+IceInternal::getInterfacesForMulticast(const string& interface, const Address& mcastAddr)
+{
+ int protocolSupport = getProtocolSupport(mcastAddr);
+ vector<string> interfaces = getHostsForEndpointExpand(interface, protocolSupport, true);
+ if(interfaces.empty())
+ {
+ interfaces.push_back(interface);
+ }
+ return interfaces;
+}
#else
vector<string>
IceInternal::getHostsForEndpointExpand(const string& host, ProtocolSupport protocolSupport, bool includeLoopback)
@@ -1669,6 +1694,27 @@ IceInternal::getHostsForEndpointExpand(const string& host, ProtocolSupport proto
}
return hosts; // An empty host list indicates to just use the given host.
}
+
+vector<string>
+IceInternal::getInterfacesForMulticast(const string& interface, const Address& mcastAddr)
+{
+ ProtocolSupport protocolSupport = getProtocolSupport(mcastAddr);
+ vector<string> interfaces;
+ bool ipv4Wildcard = false;
+ if(isWildcard(interface, protocolSupport, ipv4Wildcard))
+ {
+ vector<Address> addrs = getLocalAddresses(ipv4Wildcard ? EnableIPv4 : protocolSupport, true);
+ for(vector<Address>::const_iterator p = addrs.begin(); p != addrs.end(); ++p)
+ {
+ interfaces.push_back(inetAddrToString(*p)); // We keep link local addresses for multicast
+ }
+ }
+ if(interfaces.empty())
+ {
+ interfaces.push_back(interface);
+ }
+ return interfaces;
+}
#endif
string
@@ -2019,15 +2065,11 @@ IceInternal::getRecvBufferSize(SOCKET fd)
void
IceInternal::setMcastGroup(SOCKET fd, const Address& group, const string& intf)
{
- vector<string> interfaces = getHostsForEndpointExpand(intf, getProtocolSupport(group), true);
- if(interfaces.empty())
- {
- interfaces.push_back(intf);
- }
-
+ vector<string> interfaces = getInterfacesForMulticast(intf, group);
+ set<int> indexes;
for(vector<string>::const_iterator p = interfaces.begin(); p != interfaces.end(); ++p)
{
- int rc;
+ int rc = 0;
if(group.saStorage.ss_family == AF_INET)
{
struct ip_mreq mreq;
@@ -2037,10 +2079,15 @@ IceInternal::setMcastGroup(SOCKET fd, const Address& group, const string& intf)
}
else
{
- struct ipv6_mreq mreq;
- mreq.ipv6mr_multiaddr = group.saIn6.sin6_addr;
- mreq.ipv6mr_interface = getInterfaceIndex(*p);
- rc = setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, reinterpret_cast<char*>(&mreq), int(sizeof(mreq)));
+ int index = getInterfaceIndex(*p);
+ if(indexes.find(index) == indexes.end()) // Don't join twice the same interface (if it has multiple IPs)
+ {
+ indexes.insert(index);
+ struct ipv6_mreq mreq;
+ mreq.ipv6mr_multiaddr = group.saIn6.sin6_addr;
+ mreq.ipv6mr_interface = index;
+ rc = setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, reinterpret_cast<char*>(&mreq), int(sizeof(mreq)));
+ }
}
if(rc == SOCKET_ERROR)
{
diff --git a/cpp/src/Ice/Network.h b/cpp/src/Ice/Network.h
index 788470f2708..ccf05b74663 100755
--- a/cpp/src/Ice/Network.h
+++ b/cpp/src/Ice/Network.h
@@ -284,6 +284,7 @@ ICE_API std::string addressesToString(const Address&, const Address&, bool);
ICE_API bool isAddressValid(const Address&);
ICE_API std::vector<std::string> getHostsForEndpointExpand(const std::string&, ProtocolSupport, bool);
+ICE_API std::vector<std::string> getInterfacesForMulticast(const std::string&, const Address&);
ICE_API std::string inetAddrToString(const Address&);
ICE_API int getPort(const Address&);
diff --git a/cpp/src/Ice/UdpTransceiver.cpp b/cpp/src/Ice/UdpTransceiver.cpp
index b4f5520c184..9d32c38938e 100755
--- a/cpp/src/Ice/UdpTransceiver.cpp
+++ b/cpp/src/Ice/UdpTransceiver.cpp
@@ -771,11 +771,14 @@ IceInternal::UdpTransceiver::toDetailedString() const
{
ostringstream os;
os << toString();
- string addr = isAddressValid(_mcastAddr) ? _mcastInterface : inetAddrToString(_addr);
- vector<string> intfs = getHostsForEndpointExpand(addr, _instance->protocolSupport(), true);
- if(isAddressValid(_mcastAddr) && intfs.empty())
+ vector<string> intfs;
+ if(isAddressValid(_mcastAddr))
+ {
+ intfs = getInterfacesForMulticast(_mcastInterface, _mcastAddr);
+ }
+ else
{
- intfs.push_back(_mcastInterface);
+ intfs = getHostsForEndpointExpand(inetAddrToString(_addr), _instance->protocolSupport(), true);
}
if(!intfs.empty())
{
diff --git a/csharp/src/Ice/Network.cs b/csharp/src/Ice/Network.cs
index 2d410d6a944..be375cc0526 100644
--- a/csharp/src/Ice/Network.cs
+++ b/csharp/src/Ice/Network.cs
@@ -456,40 +456,39 @@ namespace IceInternal
{
try
{
- int protocolSupport = group.AddressFamily == AddressFamily.InterNetwork ? EnableIPv4 : EnableIPv6;
- List<string> interfaces = getHostsForEndpointExpand(iface, protocolSupport, true);
- if(interfaces.Count == 0)
- {
- interfaces.Add(iface);
- }
- foreach(string intf in interfaces)
+ var indexes = new HashSet<int>();
+ foreach(string intf in getInterfacesForMulticast(iface, group))
{
int index = getInterfaceIndex(intf, group.AddressFamily);
- if(group.AddressFamily == AddressFamily.InterNetwork)
+ if(!indexes.Contains(index))
{
- MulticastOption option;
- if(index == -1)
- {
- option = new MulticastOption(group);
- }
- else
+ indexes.Add(index);
+ if(group.AddressFamily == AddressFamily.InterNetwork)
{
- option = new MulticastOption(group, index);
- }
- s.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, option);
- }
- else
- {
- IPv6MulticastOption option;
- if(index == -1)
- {
- option = new IPv6MulticastOption(group);
+ MulticastOption option;
+ if(index == -1)
+ {
+ option = new MulticastOption(group);
+ }
+ else
+ {
+ option = new MulticastOption(group, index);
+ }
+ s.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, option);
}
else
{
- option = new IPv6MulticastOption(group, index);
+ IPv6MulticastOption option;
+ if(index == -1)
+ {
+ option = new IPv6MulticastOption(group);
+ }
+ else
+ {
+ option = new IPv6MulticastOption(group, index);
+ }
+ s.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.AddMembership, option);
}
- s.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.AddMembership, option);
}
}
}
@@ -936,23 +935,9 @@ namespace IceInternal
public static List<string> getHostsForEndpointExpand(string host, int protocol, bool includeLoopback)
{
- bool wildcard = host.Length == 0;
- bool ipv4Wildcard = false;
- if(!wildcard)
- {
- try
- {
- IPAddress addr = IPAddress.Parse(host);
- ipv4Wildcard = addr.Equals(IPAddress.Any);
- wildcard = ipv4Wildcard || addr.Equals(IPAddress.IPv6Any);
- }
- catch(Exception)
- {
- }
- }
-
List<string> hosts = new List<string>();
- if(wildcard)
+ bool ipv4Wildcard = false;
+ if(isWildcard(host, out ipv4Wildcard))
{
IPAddress[] addrs = getLocalAddresses(ipv4Wildcard ? EnableIPv4 : protocol, includeLoopback);
foreach(IPAddress a in addrs)
@@ -966,6 +951,26 @@ namespace IceInternal
return hosts;
}
+ public static List<string> getInterfacesForMulticast(string intf, IPAddress group)
+ {
+ List<string> interfaces = new List<string>();
+ bool ipv4Wildcard = false;
+ int protocol = group.AddressFamily == AddressFamily.InterNetwork ? EnableIPv4 : EnableIPv6;
+ if(isWildcard(intf, out ipv4Wildcard))
+ {
+ IPAddress[] addrs = getLocalAddresses(ipv4Wildcard ? EnableIPv4 : protocol, true);
+ foreach(IPAddress a in addrs)
+ {
+ interfaces.Add(a.ToString());
+ }
+ }
+ if(interfaces.Count == 0)
+ {
+ interfaces.Add(intf);
+ }
+ return interfaces;
+ }
+
public static string fdToString(Socket socket, NetworkProxy proxy, EndPoint target)
{
try
@@ -1181,6 +1186,32 @@ namespace IceInternal
return addr;
}
+ private static bool
+ isWildcard(string address, out bool ipv4Wildcard)
+ {
+ ipv4Wildcard = false;
+ if(address.Length == 0)
+ {
+ return true;
+ }
+
+ try
+ {
+ IPAddress addr = IPAddress.Parse(address);
+ if(addr.Equals(IPAddress.Any))
+ {
+ ipv4Wildcard = true;
+ return true;
+ }
+ return addr.Equals(IPAddress.IPv6Any);
+ }
+ catch(Exception)
+ {
+ }
+
+ return false;
+ }
+
public static bool
addressEquals(EndPoint addr1, EndPoint addr2)
{
diff --git a/csharp/src/Ice/UdpTransceiver.cs b/csharp/src/Ice/UdpTransceiver.cs
index 05f569c7b40..00a5e0d10dc 100644
--- a/csharp/src/Ice/UdpTransceiver.cs
+++ b/csharp/src/Ice/UdpTransceiver.cs
@@ -652,11 +652,15 @@ namespace IceInternal
public string toDetailedString()
{
StringBuilder s = new StringBuilder(ToString());
- string addr = _mcastAddr != null ? _mcastInterface : Network.endpointAddressToString(_addr);
- List<string> intfs = Network.getHostsForEndpointExpand(addr, _instance.protocolSupport(), true);
- if(_mcastAddr != null && intfs.Count == 0)
+ List<string> intfs;
+ if(_mcastAddr == null)
{
- intfs.Add(_mcastInterface);
+ intfs = Network.getHostsForEndpointExpand(Network.endpointAddressToString(_addr),
+ _instance.protocolSupport(), true);
+ }
+ else
+ {
+ intfs = Network.getInterfacesForMulticast(_mcastInterface, _mcastAddr.Address);
}
if(intfs.Count != 0)
{
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 7ee1da0cf58..9a96429a68c 100644
--- a/java-compat/src/Ice/src/main/java/IceInternal/Network.java
+++ b/java-compat/src/Ice/src/main/java/IceInternal/Network.java
@@ -297,14 +297,15 @@ public final class Network
{
try
{
- java.util.List<String> interfaces = getHostsForEndpointExpand(intf, getProtocolSupport(group), true);
- if(interfaces.isEmpty())
+ java.util.Set<java.net.NetworkInterface> interfaces = new java.util.HashSet<>();
+ for(String address : getInterfacesForMulticast(intf, group))
{
- interfaces.add(intf);
- }
- for(String intf2 : interfaces)
- {
- fd.join(group.getAddress(), getInterface(intf2));
+ java.net.NetworkInterface intf2 = getInterface(address);
+ if(!interfaces.contains(intf2))
+ {
+ interfaces.add(intf2);
+ fd.join(group.getAddress(), intf2);
+ }
}
}
catch(Exception ex)
@@ -1021,24 +1022,8 @@ public final class Network
public static java.util.ArrayList<String>
getHostsForEndpointExpand(String host, int protocolSupport, boolean includeLoopback)
{
- boolean wildcard = (host == null || host.length() == 0);
- if(!wildcard)
- {
- try
- {
- wildcard = java.net.InetAddress.getByName(host).isAnyLocalAddress();
- }
- catch(java.net.UnknownHostException ex)
- {
- }
- catch(java.lang.SecurityException ex)
- {
- throw new Ice.SocketException(ex);
- }
- }
-
java.util.ArrayList<String> hosts = new java.util.ArrayList<String>();
- if(wildcard)
+ if(isWildcard(host))
{
java.util.ArrayList<java.net.InetAddress> addrs = getLocalAddresses(protocolSupport);
for(java.net.InetAddress addr : addrs)
@@ -1069,6 +1054,34 @@ public final class Network
return hosts;
}
+ public static java.util.ArrayList<String>
+ getInterfacesForMulticast(String intf, java.net.InetSocketAddress mcastAddr)
+ {
+ int protocolSupport = getProtocolSupport(mcastAddr);
+ java.util.ArrayList<String> interfaces = new java.util.ArrayList<>();
+ if(isWildcard(intf))
+ {
+ java.util.ArrayList<java.net.InetAddress> addrs = getLocalAddresses(protocolSupport);
+ for(java.net.InetAddress addr : addrs)
+ {
+ interfaces.add(addr.getHostAddress());
+ }
+ if(protocolSupport != EnableIPv6)
+ {
+ interfaces.add("127.0.0.1");
+ }
+ if(protocolSupport != EnableIPv4)
+ {
+ interfaces.add("0:0:0:0:0:0:0:1");
+ }
+ }
+ if(interfaces.isEmpty())
+ {
+ interfaces.add(intf);
+ }
+ return interfaces;
+ }
+
public static void
setTcpBufSize(java.nio.channels.SocketChannel socket, ProtocolInstance instance)
{
@@ -1402,6 +1415,27 @@ public final class Network
return addr;
}
+ private static boolean
+ isWildcard(String host)
+ {
+ if(host == null || host.length() == 0)
+ {
+ return true;
+ }
+ try
+ {
+ return java.net.InetAddress.getByName(host).isAnyLocalAddress();
+ }
+ catch(java.net.UnknownHostException ex)
+ {
+ }
+ catch(java.lang.SecurityException ex)
+ {
+ throw new Ice.SocketException(ex);
+ }
+ return false;
+ }
+
static class IPAddressComparator implements java.util.Comparator<java.net.InetSocketAddress>
{
IPAddressComparator(boolean ipv6)
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 fe6f67d295e..f6fceb03c6a 100644
--- a/java-compat/src/Ice/src/main/java/IceInternal/UdpTransceiver.java
+++ b/java-compat/src/Ice/src/main/java/IceInternal/UdpTransceiver.java
@@ -282,11 +282,15 @@ final class UdpTransceiver implements Transceiver
public String toDetailedString()
{
StringBuilder s = new StringBuilder(toString());
- String addr = _mcastAddr != null ? _mcastInterface : _addr.getAddress().getHostAddress();
- java.util.List<String> intfs = Network.getHostsForEndpointExpand(addr, _instance.protocolSupport(), true);
- if(_mcastAddr != null && intfs.isEmpty())
+ java.util.List<String> intfs;
+ if(_mcastAddr == null)
{
- intfs.add(_mcastInterface);
+ intfs = Network.getHostsForEndpointExpand(_addr.getAddress().getHostAddress(), _instance.protocolSupport(),
+ true);
+ }
+ else
+ {
+ intfs = Network.getInterfacesForMulticast(_mcastInterface, _mcastAddr);
}
if(!intfs.isEmpty())
{
diff --git a/java/src/Ice/src/main/java/com/zeroc/IceInternal/Network.java b/java/src/Ice/src/main/java/com/zeroc/IceInternal/Network.java
index 9a0a8a72538..acbba6dccf2 100644
--- a/java/src/Ice/src/main/java/com/zeroc/IceInternal/Network.java
+++ b/java/src/Ice/src/main/java/com/zeroc/IceInternal/Network.java
@@ -302,14 +302,15 @@ public final class Network
{
try
{
- java.util.List<String> interfaces = getHostsForEndpointExpand(intf, getProtocolSupport(group), true);
- if(interfaces.isEmpty())
+ java.util.Set<java.net.NetworkInterface> interfaces = new java.util.HashSet<>();
+ for(String address : getInterfacesForMulticast(intf, group))
{
- interfaces.add(intf);
- }
- for(String intf2 : interfaces)
- {
- fd.join(group.getAddress(), getInterface(intf2));
+ java.net.NetworkInterface intf2 = getInterface(address);
+ if(!interfaces.contains(intf2))
+ {
+ interfaces.add(intf2);
+ fd.join(group.getAddress(), intf2);
+ }
}
}
catch(Exception ex)
@@ -1026,24 +1027,8 @@ public final class Network
public static java.util.ArrayList<String>
getHostsForEndpointExpand(String host, int protocolSupport, boolean includeLoopback)
{
- boolean wildcard = (host == null || host.length() == 0);
- if(!wildcard)
- {
- try
- {
- wildcard = java.net.InetAddress.getByName(host).isAnyLocalAddress();
- }
- catch(java.net.UnknownHostException ex)
- {
- }
- catch(java.lang.SecurityException ex)
- {
- throw new SocketException(ex);
- }
- }
-
java.util.ArrayList<String> hosts = new java.util.ArrayList<>();
- if(wildcard)
+ if(isWildcard(host))
{
java.util.ArrayList<java.net.InetAddress> addrs = getLocalAddresses(protocolSupport);
for(java.net.InetAddress addr : addrs)
@@ -1074,6 +1059,34 @@ public final class Network
return hosts;
}
+ public static java.util.ArrayList<String>
+ getInterfacesForMulticast(String intf, java.net.InetSocketAddress mcastAddr)
+ {
+ int protocolSupport = getProtocolSupport(mcastAddr);
+ java.util.ArrayList<String> interfaces = new java.util.ArrayList<>();
+ if(isWildcard(intf))
+ {
+ java.util.ArrayList<java.net.InetAddress> addrs = getLocalAddresses(protocolSupport);
+ for(java.net.InetAddress addr : addrs)
+ {
+ interfaces.add(addr.getHostAddress());
+ }
+ if(protocolSupport != EnableIPv6)
+ {
+ interfaces.add("127.0.0.1");
+ }
+ if(protocolSupport != EnableIPv4)
+ {
+ interfaces.add("0:0:0:0:0:0:0:1");
+ }
+ }
+ if(interfaces.isEmpty())
+ {
+ interfaces.add(intf);
+ }
+ return interfaces;
+ }
+
public static void
setTcpBufSize(java.nio.channels.SocketChannel socket, ProtocolInstance instance)
{
@@ -1407,6 +1420,27 @@ public final class Network
return addr;
}
+ private static boolean
+ isWildcard(String host)
+ {
+ if(host == null || host.length() == 0)
+ {
+ return true;
+ }
+ try
+ {
+ return java.net.InetAddress.getByName(host).isAnyLocalAddress();
+ }
+ catch(java.net.UnknownHostException ex)
+ {
+ }
+ catch(java.lang.SecurityException ex)
+ {
+ throw new SocketException(ex);
+ }
+ return false;
+ }
+
static class IPAddressComparator implements java.util.Comparator<java.net.InetSocketAddress>
{
IPAddressComparator(boolean ipv6)
diff --git a/java/src/Ice/src/main/java/com/zeroc/IceInternal/UdpTransceiver.java b/java/src/Ice/src/main/java/com/zeroc/IceInternal/UdpTransceiver.java
index 885e0cb9175..fd3b2834853 100644
--- a/java/src/Ice/src/main/java/com/zeroc/IceInternal/UdpTransceiver.java
+++ b/java/src/Ice/src/main/java/com/zeroc/IceInternal/UdpTransceiver.java
@@ -282,11 +282,15 @@ final class UdpTransceiver implements Transceiver
public String toDetailedString()
{
StringBuilder s = new StringBuilder(toString());
- String addr = _mcastAddr != null ? _mcastInterface : _addr.getAddress().getHostAddress();
- java.util.List<String> intfs = Network.getHostsForEndpointExpand(addr, _instance.protocolSupport(), true);
- if(_mcastAddr != null && intfs.isEmpty())
+ java.util.List<String> intfs;
+ if(_mcastAddr == null)
{
- intfs.add(_mcastInterface);
+ intfs = Network.getHostsForEndpointExpand(_addr.getAddress().getHostAddress(), _instance.protocolSupport(),
+ true);
+ }
+ else
+ {
+ intfs = Network.getInterfacesForMulticast(_mcastInterface, _mcastAddr);
}
if(!intfs.isEmpty())
{