summaryrefslogtreecommitdiff
path: root/cpp/src/Ice/Network.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/Ice/Network.cpp')
-rw-r--r--cpp/src/Ice/Network.cpp174
1 files changed, 94 insertions, 80 deletions
diff --git a/cpp/src/Ice/Network.cpp b/cpp/src/Ice/Network.cpp
index a9d480b2eda..d329368612e 100644
--- a/cpp/src/Ice/Network.cpp
+++ b/cpp/src/Ice/Network.cpp
@@ -30,7 +30,7 @@
#if defined(ICE_OS_WINRT)
# include <IceUtil/InputUtil.h>
# include <ppltasks.h> // For Concurrency::task
-#elif defined(_WIN32)
+#elif defined(_WIN32)
# include <winsock2.h>
# include <ws2tcpip.h>
# include <iphlpapi.h>
@@ -374,7 +374,7 @@ getLocalAddresses(ProtocolSupport protocol)
if(!(ifr[i].ifr_flags & IFF_LOOPBACK)) // Don't include loopback interface addresses
{
//
- // On Solaris the above Loopback check does not always work so we double
+ // On Solaris the above Loopback check does not always work so we double
// check the address below. Solaris also returns duplicate entries that need
// to be filtered out.
//
@@ -461,7 +461,7 @@ getInterfaceIndex(const string& name)
{
return 0;
}
-
+
int index = 0;
//
@@ -479,7 +479,7 @@ getInterfaceIndex(const string& name)
//
in6_addr addr;
bool isAddr = inet_pton(AF_INET6, name.c_str(), &addr) > 0;
-
+
#ifdef _WIN32
IP_ADAPTER_ADDRESSES addrs;
ULONG buflen = 0;
@@ -499,7 +499,7 @@ getInterfaceIndex(const string& name)
{
if(ipAddr->Address.lpSockaddr->sa_family == AF_INET6)
{
- struct sockaddr_in6* ipv6Addr =
+ struct sockaddr_in6* ipv6Addr =
reinterpret_cast<struct sockaddr_in6*>(ipAddr->Address.lpSockaddr);
if(memcmp(&addr, &ipv6Addr->sin6_addr, sizeof(in6_addr)) == 0)
{
@@ -535,7 +535,7 @@ getInterfaceIndex(const string& name)
//
// Look for an interface with a matching IP address
- //
+ //
if(isAddr)
{
# if defined(__linux) || defined(__APPLE__) || defined(__FreeBSD__)
@@ -553,7 +553,7 @@ getInterfaceIndex(const string& name)
index = if_nametoindex(curr->ifa_name);
break;
}
- }
+ }
curr = curr->ifa_next;
}
::freeifaddrs(ifap);
@@ -694,6 +694,21 @@ getInterfaceAddress(const string& name)
return addr;
}
+int
+getAddressStorageSize(const Address& addr)
+{
+ int size = 0;
+ if(addr.saStorage.ss_family == AF_INET)
+ {
+ size = sizeof(sockaddr_in);
+ }
+ else if(addr.saStorage.ss_family == AF_INET6)
+ {
+ size = sizeof(sockaddr_in6);
+ }
+ return size;
+}
+
#endif // #ifndef ICE_OS_WINRT
}
@@ -849,7 +864,7 @@ bool
IceInternal::noMoreFds(int error)
{
#if defined(ICE_OS_WINRT)
- return error == (int)SocketErrorStatus::TooManyOpenFiles;
+ return error == (int)SocketErrorStatus::TooManyOpenFiles;
#elif defined(_WIN32)
return error == WSAEMFILE;
#else
@@ -1471,6 +1486,19 @@ IceInternal::isAddressValid(const Address& addr)
#endif
}
+Address
+IceInternal::getInvalidAddress()
+{
+#ifndef ICE_OS_WINRT
+ Address addr;
+ memset(&addr.saStorage, 0, sizeof(sockaddr_storage));
+ addr.saStorage.ss_family = AF_UNSPEC;
+ return addr;
+#else
+ return Address();
+#endif
+}
+
#ifdef ICE_OS_WINRT
vector<string>
IceInternal::getHostsForEndpointExpand(const string&, ProtocolSupport, bool)
@@ -1521,16 +1549,8 @@ string
IceInternal::inetAddrToString(const Address& ss)
{
#ifndef ICE_OS_WINRT
- int size = 0;
- if(ss.saStorage.ss_family == AF_INET)
- {
- size = static_cast<int>(sizeof(sockaddr_in));
- }
- else if(ss.saStorage.ss_family == AF_INET6)
- {
- size = static_cast<int>(sizeof(sockaddr_in6));
- }
- else
+ int size = getAddressStorageSize(ss);
+ if(size == 0)
{
return "";
}
@@ -1684,7 +1704,7 @@ IceInternal::setTcpBufSize(SOCKET fd, const Ice::PropertiesPtr& properties, cons
out << "TCP receive buffer size: requested size of " << sizeRequested << " adjusted to " << size;
}
}
-
+
sizeRequested = properties->getPropertyAsIntWithDefault("Ice.TCP.SndSize", dfltBufSize);
if(sizeRequested > 0)
{
@@ -1790,7 +1810,7 @@ IceInternal::getSendBufferSize(SOCKET fd)
#ifndef ICE_OS_WINRT
int sz;
socklen_t len = sizeof(sz);
- if(getsockopt(fd, SOL_SOCKET, SO_SNDBUF, (char*)&sz, &len) == SOCKET_ERROR ||
+ if(getsockopt(fd, SOL_SOCKET, SO_SNDBUF, (char*)&sz, &len) == SOCKET_ERROR ||
static_cast<unsigned int>(len) != sizeof(sz))
{
closeSocketNoThrow(fd);
@@ -1834,7 +1854,7 @@ IceInternal::getRecvBufferSize(SOCKET fd)
#ifndef ICE_OS_WINRT
int sz;
socklen_t len = sizeof(sz);
- if(getsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char*)&sz, &len) == SOCKET_ERROR ||
+ if(getsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char*)&sz, &len) == SOCKET_ERROR ||
static_cast<unsigned int>(len) != sizeof(sz))
{
closeSocketNoThrow(fd);
@@ -1882,7 +1902,7 @@ IceInternal::setMcastGroup(SOCKET fd, const Address& group, const string&)
try
{
//
- // NOTE: WinRT doesn't allow specyfing the interface.
+ // NOTE: WinRT doesn't allow specyfing the interface.
//
safe_cast<DatagramSocket^>(fd)->JoinMulticastGroup(group.host);
}
@@ -1992,7 +2012,7 @@ IceInternal::doBind(SOCKET fd, const Address& addr)
local.host = addr.host;
local.port = listener->Information->LocalPort;
}
-
+
DatagramSocket^ datagram = dynamic_cast<DatagramSocket^>(fd);
if(datagram != nullptr)
{
@@ -2015,20 +2035,8 @@ IceInternal::doBind(SOCKET fd, const Address& addr)
}
return local;
#else
- int size;
- if(addr.saStorage.ss_family == AF_INET)
- {
- size = static_cast<int>(sizeof(sockaddr_in));
- }
- else if(addr.saStorage.ss_family == AF_INET6)
- {
- size = static_cast<int>(sizeof(sockaddr_in6));
- }
- else
- {
- assert(false);
- size = 0; // Keep the compiler happy.
- }
+ int size = getAddressStorageSize(addr);
+ assert(size != 0);
if(::bind(fd, &addr.sa, size) == SOCKET_ERROR)
{
@@ -2052,6 +2060,20 @@ IceInternal::doBind(SOCKET fd, const Address& addr)
#ifndef ICE_OS_WINRT
+Address
+IceInternal::getNumericAddress(const std::string& address)
+{
+ vector<Address> addrs = getAddresses(address, 0, EnableBoth, Ice::Ordered, false, false);
+ if(addrs.empty())
+ {
+ return getInvalidAddress();
+ }
+ else
+ {
+ return addrs[0];
+ }
+}
+
int
IceInternal::getSocketErrno()
{
@@ -2123,7 +2145,7 @@ bool
IceInternal::connectFailed()
{
#if defined(_WIN32)
- int error = WSAGetLastError();
+ int error = WSAGetLastError();
return error == WSAECONNREFUSED ||
error == WSAETIMEDOUT ||
error == WSAENETUNREACH ||
@@ -2131,7 +2153,7 @@ IceInternal::connectFailed()
error == WSAECONNRESET ||
error == WSAESHUTDOWN ||
error == WSAECONNABORTED ||
- error == ERROR_SEM_TIMEOUT ||
+ error == ERROR_SEM_TIMEOUT ||
error == ERROR_NETNAME_DELETED;
#else
return errno == ECONNREFUSED ||
@@ -2230,24 +2252,17 @@ repeatListen:
}
bool
-IceInternal::doConnect(SOCKET fd, const Address& addr)
+IceInternal::doConnect(SOCKET fd, const Address& addr, const Address& sourceAddr)
{
-repeatConnect:
- int size;
- if(addr.saStorage.ss_family == AF_INET)
+ if(isAddressValid(sourceAddr))
{
- size = static_cast<int>(sizeof(sockaddr_in));
- }
- else if(addr.saStorage.ss_family == AF_INET6)
- {
- size = static_cast<int>(sizeof(sockaddr_in6));
- }
- else
- {
- assert(false);
- size = 0; // Keep the compiler happy.
+ doBind(fd, sourceAddr);
}
+repeatConnect:
+ int size = getAddressStorageSize(addr);
+ assert(size != 0);
+
if(::connect(fd, &addr.sa, size) == SOCKET_ERROR)
{
if(interrupted())
@@ -2324,7 +2339,7 @@ IceInternal::doFinishConnect(SOCKET fd)
ex.error = getSocketErrno();
throw ex;
}
-
+
if(val > 0)
{
#if defined(_WIN32)
@@ -2430,10 +2445,10 @@ IceInternal::createPipe(SOCKET fds[2])
{
setBlock(fds[0], true);
# ifndef NDEBUG
- bool connected = doConnect(fds[0], addr);
+ bool connected = doConnect(fds[0], addr, getInvalidAddress());
assert(connected);
# else
- doConnect(fds[0], addr);
+ doConnect(fds[0], addr, getInvalidAddress());
# endif
}
catch(...)
@@ -2535,7 +2550,7 @@ IceInternal::checkConnectErrorCode(const char* file, int line, HRESULT herr, Hos
DNSException ex(file, line);
ex.error = static_cast<int>(error);
//
- // Don't need to pass a wide string converter as the wide string come from
+ // Don't need to pass a wide string converter as the wide string come from
// Windows API.
//
ex.host = IceUtil::wstringToString(host->RawName->Data(), IceUtil::getProcessStringConverter());
@@ -2586,38 +2601,37 @@ IceInternal::checkErrorCode(const char* file, int line, HRESULT herr)
#if defined(ICE_USE_IOCP)
void
-IceInternal::doConnectAsync(SOCKET fd, const Address& addr, AsyncInfo& info)
+IceInternal::doConnectAsync(SOCKET fd, const Address& addr, const Address& sourceAddr, AsyncInfo& info)
{
//
// NOTE: It's the caller's responsability to close the socket upon
// failure to connect. The socket isn't closed by this method.
//
-
Address bindAddr;
- memset(&bindAddr.saStorage, 0, sizeof(sockaddr_storage));
-
- int size;
- if(addr.saStorage.ss_family == AF_INET)
- {
- size = sizeof(sockaddr_in);
- bindAddr.saIn.sin_family = AF_INET;
- bindAddr.saIn.sin_port = htons(0);
- bindAddr.saIn.sin_addr.s_addr = htonl(INADDR_ANY);
- }
- else if(addr.saStorage.ss_family == AF_INET6)
+ if(isAddressValid(sourceAddr))
{
- size = sizeof(sockaddr_in6);
-
- bindAddr.saIn6.sin6_family = AF_INET6;
- bindAddr.saIn6.sin6_port = htons(0);
- bindAddr.saIn6.sin6_addr = in6addr_any;
+ bindAddr = sourceAddr;
}
else
{
- assert(false);
- size = 0; // Keep the compiler happy.
+ memset(&bindAddr.saStorage, 0, sizeof(sockaddr_storage));
+ if(addr.saStorage.ss_family == AF_INET)
+ {
+ bindAddr.saIn.sin_family = AF_INET;
+ bindAddr.saIn.sin_port = htons(0);
+ bindAddr.saIn.sin_addr.s_addr = htonl(INADDR_ANY);
+ }
+ else if(addr.saStorage.ss_family == AF_INET6)
+ {
+ bindAddr.saIn6.sin6_family = AF_INET6;
+ bindAddr.saIn6.sin6_port = htons(0);
+ bindAddr.saIn6.sin6_addr = in6addr_any;
+ }
}
+ int size = getAddressStorageSize(bindAddr);
+ assert(size != 0);
+
if(::bind(fd, &bindAddr.sa, size) == SOCKET_ERROR)
{
SocketException ex(__FILE__, __LINE__);
@@ -2628,20 +2642,20 @@ IceInternal::doConnectAsync(SOCKET fd, const Address& addr, AsyncInfo& info)
LPFN_CONNECTEX ConnectEx = NULL; // a pointer to the 'ConnectEx()' function
GUID GuidConnectEx = WSAID_CONNECTEX; // The Guid
DWORD dwBytes;
- if(WSAIoctl(fd,
+ if(WSAIoctl(fd,
SIO_GET_EXTENSION_FUNCTION_POINTER,
&GuidConnectEx,
sizeof(GuidConnectEx),
&ConnectEx,
sizeof(ConnectEx),
&dwBytes,
- NULL,
+ NULL,
NULL) == SOCKET_ERROR)
{
SocketException ex(__FILE__, __LINE__);
ex.error = getSocketErrno();
throw ex;
- }
+ }
if(!ConnectEx(fd, &addr.sa, size, 0, 0, 0, &info))
{