summaryrefslogtreecommitdiff
path: root/cpp/src/Ice/UdpTransceiver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/Ice/UdpTransceiver.cpp')
-rw-r--r--cpp/src/Ice/UdpTransceiver.cpp78
1 files changed, 56 insertions, 22 deletions
diff --git a/cpp/src/Ice/UdpTransceiver.cpp b/cpp/src/Ice/UdpTransceiver.cpp
index 2736587f7a8..1d889d686de 100644
--- a/cpp/src/Ice/UdpTransceiver.cpp
+++ b/cpp/src/Ice/UdpTransceiver.cpp
@@ -72,7 +72,7 @@ IceInternal::UdpTransceiver::shutdownReadWrite()
//
// Save the local address before shutting down or disconnecting.
//
- struct sockaddr_in localAddr;
+ struct sockaddr_storage localAddr;
fdToLocalAddress(_fd, localAddr);
assert(_fd != INVALID_SOCKET);
@@ -84,9 +84,9 @@ IceInternal::UdpTransceiver::shutdownReadWrite()
//
if(!_connect)
{
- struct sockaddr_in unspec;
+ struct sockaddr_storage unspec;
memset(&unspec, 0, sizeof(unspec));
- unspec.sin_family = AF_UNSPEC;
+ unspec.ss_family = AF_UNSPEC;
::connect(_fd, reinterpret_cast<struct sockaddr*>(&unspec), int(sizeof(unspec)));
}
@@ -94,7 +94,7 @@ IceInternal::UdpTransceiver::shutdownReadWrite()
// Send a dummy packet to the socket. This packet is ignored because we have
// already set _shutdownReadWrite.
//
- SOCKET fd = createSocket(true);
+ SOCKET fd = createSocket(true, localAddr.ss_family);
setBlock(fd, false);
doConnect(fd, localAddr, -1);
::send(fd, "", 1, 0);
@@ -259,8 +259,8 @@ repeat:
// If we must connect, then we connect to the first peer that
// sends us a packet.
//
- struct sockaddr_in peerAddr;
- memset(&peerAddr, 0, sizeof(struct sockaddr_in));
+ struct sockaddr_storage peerAddr;
+ memset(&peerAddr, 0, sizeof(struct sockaddr_storage));
socklen_t len = static_cast<socklen_t>(sizeof(peerAddr));
assert(_fd != INVALID_SOCKET);
ret = recvfrom(_fd, reinterpret_cast<char*>(&buf.b[0]), packetSize,
@@ -374,7 +374,7 @@ IceInternal::UdpTransceiver::toString() const
{
if(_mcastServer && _fd != INVALID_SOCKET)
{
- struct sockaddr_in remoteAddr;
+ struct sockaddr_storage remoteAddr;
bool peerConnected = fdToRemoteAddress(_fd, remoteAddr);
return addressesToString(_addr, remoteAddr, peerConnected);
}
@@ -407,10 +407,10 @@ IceInternal::UdpTransceiver::checkSendSize(const Buffer& buf, size_t messageSize
int
IceInternal::UdpTransceiver::effectivePort() const
{
- return ntohs(_addr.sin_port);
+ return getPort(_addr);
}
-IceInternal::UdpTransceiver::UdpTransceiver(const InstancePtr& instance, const struct sockaddr_in& addr,
+IceInternal::UdpTransceiver::UdpTransceiver(const InstancePtr& instance, const struct sockaddr_storage& addr,
const string& mcastInterface, int mcastTtl) :
_traceLevels(instance->traceLevels()),
_logger(instance->initializationData().logger),
@@ -423,18 +423,35 @@ IceInternal::UdpTransceiver::UdpTransceiver(const InstancePtr& instance, const s
{
try
{
- _fd = createSocket(true);
+ _fd = createSocket(true, _addr.ss_family);
setBufSize(instance);
setBlock(_fd, false);
doConnect(_fd, _addr, -1);
_connect = false; // We're connected now
- if(IN_MULTICAST(ntohl(_addr.sin_addr.s_addr)))
+
+ bool multicast = false;
+ int port;
+ if(_addr.ss_family == AF_INET)
+ {
+ struct sockaddr_in* addrin = reinterpret_cast<struct sockaddr_in*>(&_addr);
+ 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_in addr;
- getAddress(mcastInterface, ntohs(_addr.sin_port), addr);
- setMcastInterface(_fd, addr.sin_addr);
+ struct sockaddr_storage addr;
+ getAddress(mcastInterface, port, addr, instance->protocolSupport());
+ setMcastInterface(_fd, reinterpret_cast<struct sockaddr_in*>(&addr)->sin_addr);
}
if(mcastTtl != -1)
{
@@ -472,39 +489,56 @@ IceInternal::UdpTransceiver::UdpTransceiver(const InstancePtr& instance, const s
{
try
{
- _fd = createSocket(true);
+ getAddressForServer(host, port, _addr, instance->protocolSupport());
+ _fd = createSocket(true, _addr.ss_family);
setBufSize(instance);
setBlock(_fd, false);
- getAddress(host, port, _addr);
if(_traceLevels->network >= 2)
{
Trace out(_logger, _traceLevels->networkCat);
out << "attempting to bind to udp socket " << addrToString(_addr);
}
- if(IN_MULTICAST(ntohl(_addr.sin_addr.s_addr)))
+ bool multicast = false;
+ int port;
+ if(_addr.ss_family == AF_INET)
+ {
+ struct sockaddr_in* addrin = reinterpret_cast<struct sockaddr_in*>(&_addr);
+ 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);
- struct sockaddr_in addr;
+ struct sockaddr_storage addr;
//
// Windows does not allow binding to the mcast address itself
// so we bind to INADDR_ANY (0.0.0.0) instead.
//
#ifdef _WIN32
- getAddress("0.0.0.0", port, addr);
+ getAddressForServer("", port, addr, instance->protocolSupport());
doBind(_fd, addr);
#else
doBind(_fd, _addr);
#endif
+ struct sockaddr_in* maddr = reinterpret_cast<sockaddr_in*>(&addr);
if(mcastInterface.length() > 0)
{
- getAddress(mcastInterface, port, addr);
+ getAddress(mcastInterface, port, addr, instance->protocolSupport());
}
else
{
- addr.sin_addr.s_addr = INADDR_ANY;
+ maddr->sin_addr.s_addr = INADDR_ANY;
}
- setMcastGroup(_fd, _addr.sin_addr, addr.sin_addr);
+ setMcastGroup(_fd, reinterpret_cast<struct sockaddr_in*>(&_addr)->sin_addr, maddr->sin_addr);
_mcastServer = true;
}
else