summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
authorDwayne Boone <dwayne@zeroc.com>2008-01-21 16:20:48 -0330
committerDwayne Boone <dwayne@zeroc.com>2008-01-21 16:20:48 -0330
commit4489afe7b04f40bcab6e5b967ffe3691eb630340 (patch)
treedce79758081370ab48773fa0d4fa1e69d9e70a5f /cpp/src
parentAdd VC6 fix to mcpp patch (diff)
downloadice-4489afe7b04f40bcab6e5b967ffe3691eb630340.tar.bz2
ice-4489afe7b04f40bcab6e5b967ffe3691eb630340.tar.xz
ice-4489afe7b04f40bcab6e5b967ffe3691eb630340.zip
Fixed the multicast support for IPv6
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/Ice/Network.cpp54
-rw-r--r--cpp/src/Ice/Network.h6
-rw-r--r--cpp/src/Ice/UdpTransceiver.cpp21
3 files changed, 51 insertions, 30 deletions
diff --git a/cpp/src/Ice/Network.cpp b/cpp/src/Ice/Network.cpp
index 5e6f5bfba0a..02b2ce85fba 100644
--- a/cpp/src/Ice/Network.cpp
+++ b/cpp/src/Ice/Network.cpp
@@ -815,12 +815,26 @@ IceInternal::getRecvBufferSize(SOCKET fd)
}
void
-IceInternal::setMcastGroup(SOCKET fd, const struct in_addr& group, const struct in_addr& interface)
+IceInternal::setMcastGroup(SOCKET fd, const struct sockaddr_storage& group, const string& interface)
{
- struct ip_mreq mreq;
- mreq.imr_multiaddr = group;
- mreq.imr_interface = interface;
- if(setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&mreq, int(sizeof(mreq))) == SOCKET_ERROR)
+ int rc;
+ if(group.ss_family == AF_INET)
+ {
+ struct ip_mreq mreq;
+ mreq.imr_multiaddr = reinterpret_cast<const struct sockaddr_in*>(&group)->sin_addr;
+ struct sockaddr_storage addr;
+ getAddress(interface, 0, addr, EnableIPv4);
+ mreq.imr_interface = reinterpret_cast<const struct sockaddr_in*>(&addr)->sin_addr;
+ rc = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&mreq, int(sizeof(mreq)));
+ }
+ else
+ {
+ struct ipv6_mreq mreq;
+ mreq.ipv6mr_multiaddr = reinterpret_cast<const struct sockaddr_in6*>(&group)->sin6_addr;
+ mreq.ipv6mr_interface = atoi(interface.c_str());
+ rc = setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, (char*)&mreq, int(sizeof(mreq)));
+ }
+ if(rc == SOCKET_ERROR)
{
closeSocketNoThrow(fd);
SocketException ex(__FILE__, __LINE__);
@@ -830,9 +844,22 @@ IceInternal::setMcastGroup(SOCKET fd, const struct in_addr& group, const struct
}
void
-IceInternal::setMcastInterface(SOCKET fd, const struct in_addr& interface)
+IceInternal::setMcastInterface(SOCKET fd, const string& interface, bool IPv4)
{
- if(setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, (char*)&interface, int(sizeof(interface))) == SOCKET_ERROR)
+ int rc;
+ if(IPv4)
+ {
+ struct sockaddr_storage addr;
+ getAddress(interface, 0, addr, EnableIPv4);
+ struct in_addr iface = reinterpret_cast<const struct sockaddr_in*>(&addr)->sin_addr;
+ rc = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, (char*)&iface, int(sizeof(iface)));
+ }
+ else
+ {
+ int interfaceNum = atoi(interface.c_str());
+ rc = setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, (char*)&interfaceNum, int(sizeof(int)));
+ }
+ if(rc == SOCKET_ERROR)
{
closeSocketNoThrow(fd);
SocketException ex(__FILE__, __LINE__);
@@ -842,9 +869,18 @@ IceInternal::setMcastInterface(SOCKET fd, const struct in_addr& interface)
}
void
-IceInternal::setMcastTtl(SOCKET fd, int ttl)
+IceInternal::setMcastTtl(SOCKET fd, int ttl, bool IPv4)
{
- if(setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&ttl, int(sizeof(int))) == SOCKET_ERROR)
+ int rc;
+ if(IPv4)
+ {
+ rc = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&ttl, int(sizeof(int)));
+ }
+ else
+ {
+ rc = setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char*)&ttl, int(sizeof(int)));
+ }
+ if(rc == SOCKET_ERROR)
{
closeSocketNoThrow(fd);
SocketException ex(__FILE__, __LINE__);
diff --git a/cpp/src/Ice/Network.h b/cpp/src/Ice/Network.h
index d5ba13de419..ed09190e27b 100644
--- a/cpp/src/Ice/Network.h
+++ b/cpp/src/Ice/Network.h
@@ -91,9 +91,9 @@ ICE_API void setSendBufferSize(SOCKET, int);
ICE_API int getSendBufferSize(SOCKET);
ICE_API void setRecvBufferSize(SOCKET, int);
ICE_API int getRecvBufferSize(SOCKET);
-ICE_API void setMcastGroup(SOCKET, const struct in_addr&, const struct in_addr&);
-ICE_API void setMcastInterface(SOCKET, const struct in_addr&);
-ICE_API void setMcastTtl(SOCKET, int);
+ICE_API void setMcastGroup(SOCKET, const struct sockaddr_storage&, const std::string&);
+ICE_API void setMcastInterface(SOCKET, const std::string&, bool);
+ICE_API void setMcastTtl(SOCKET, int, bool);
ICE_API void setReuseAddress(SOCKET, bool);
ICE_API void doBind(SOCKET, struct sockaddr_storage&);
diff --git a/cpp/src/Ice/UdpTransceiver.cpp b/cpp/src/Ice/UdpTransceiver.cpp
index 1d889d686de..96d17fc3bcb 100644
--- a/cpp/src/Ice/UdpTransceiver.cpp
+++ b/cpp/src/Ice/UdpTransceiver.cpp
@@ -437,25 +437,21 @@ IceInternal::UdpTransceiver::UdpTransceiver(const InstancePtr& instance, const s
multicast = IN_MULTICAST(ntohl(addrin->sin_addr.s_addr));
port = ntohs(addrin->sin_port);
}
- /*
else
{
struct sockaddr_in6* addrin = reinterpret_cast<struct sockaddr_in6*>(&_addr);
multicast = IN6_IS_ADDR_MULTICAST(&addrin->sin6_addr);
port = ntohs(addrin->sin6_port);
}
- */
if(multicast)
{
if(mcastInterface.length() > 0)
{
- struct sockaddr_storage addr;
- getAddress(mcastInterface, port, addr, instance->protocolSupport());
- setMcastInterface(_fd, reinterpret_cast<struct sockaddr_in*>(&addr)->sin_addr);
+ setMcastInterface(_fd, mcastInterface, _addr.ss_family == AF_INET);
}
if(mcastTtl != -1)
{
- setMcastTtl(_fd, mcastTtl);
+ setMcastTtl(_fd, mcastTtl, _addr.ss_family == AF_INET);
}
}
@@ -506,14 +502,12 @@ IceInternal::UdpTransceiver::UdpTransceiver(const InstancePtr& instance, const s
multicast = IN_MULTICAST(ntohl(addrin->sin_addr.s_addr));
port = ntohs(addrin->sin_port);
}
- /*
else
{
struct sockaddr_in6* addrin = reinterpret_cast<struct sockaddr_in6*>(&_addr);
multicast = IN6_IS_ADDR_MULTICAST(&addrin->sin6_addr);
port = ntohs(addrin->sin6_port);
}
- */
if(multicast)
{
setReuseAddress(_fd, true);
@@ -529,16 +523,7 @@ IceInternal::UdpTransceiver::UdpTransceiver(const InstancePtr& instance, const s
#else
doBind(_fd, _addr);
#endif
- struct sockaddr_in* maddr = reinterpret_cast<sockaddr_in*>(&addr);
- if(mcastInterface.length() > 0)
- {
- getAddress(mcastInterface, port, addr, instance->protocolSupport());
- }
- else
- {
- maddr->sin_addr.s_addr = INADDR_ANY;
- }
- setMcastGroup(_fd, reinterpret_cast<struct sockaddr_in*>(&_addr)->sin_addr, maddr->sin_addr);
+ setMcastGroup(_fd, _addr, mcastInterface);
_mcastServer = true;
}
else