aboutsummaryrefslogtreecommitdiff
path: root/src/netbase.cpp
diff options
context:
space:
mode:
authorPieter Wuille <pieter.wuille@gmail.com>2012-05-11 15:28:59 +0200
committerPieter Wuille <pieter.wuille@gmail.com>2012-05-11 15:29:20 +0200
commit8f10a2889089af1b2ac64802360494b54c8c7ff1 (patch)
tree06df6b9e6114b170fca7aaa7e205c26207a0ab2f /src/netbase.cpp
parent7fa4443f77a659031e277337770b506fcf954d69 (diff)
Separate listening sockets, -bind=<addr>
Diffstat (limited to 'src/netbase.cpp')
-rw-r--r--src/netbase.cpp103
1 files changed, 56 insertions, 47 deletions
diff --git a/src/netbase.cpp b/src/netbase.cpp
index 7e9620d9ff..ebf823e899 100644
--- a/src/netbase.cpp
+++ b/src/netbase.cpp
@@ -183,7 +183,12 @@ bool static Socks4(const CService &addrDest, SOCKET& hSocket)
}
char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user";
struct sockaddr_in addr;
- addrDest.GetSockAddr(&addr);
+ socklen_t len = sizeof(addr);
+ if (!addrDest.GetSockAddr((struct sockaddr*)&addr, &len) || addr.sin_family != AF_INET)
+ {
+ closesocket(hSocket);
+ return error("Cannot get proxy destination address");
+ }
memcpy(pszSocks4IP + 2, &addr.sin_port, 2);
memcpy(pszSocks4IP + 4, &addr.sin_addr, 4);
char* pszSocks4 = pszSocks4IP;
@@ -319,37 +324,18 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe
{
hSocketRet = INVALID_SOCKET;
- struct sockaddr_storage sockaddr;
- int nFamily = 0;
- size_t nSockAddrLen = 0;
-
- if (addrConnect.IsIPv4())
- {
- // Use IPv4 stack to connect to IPv4 addresses
- struct sockaddr_in sockaddr4;
- if (!addrConnect.GetSockAddr(&sockaddr4))
- return false;
- memcpy(&sockaddr, &sockaddr4, sizeof(sockaddr4));
- nSockAddrLen = sizeof(sockaddr4);
- nFamily = AF_INET;
- }
#ifdef USE_IPV6
- else if (addrConnect.IsIPv6())
- {
- struct sockaddr_in6 sockaddr6;
- if (!addrConnect.GetSockAddr6(&sockaddr6))
- return false;
- memcpy(&sockaddr, &sockaddr6, sizeof(sockaddr6));
- nSockAddrLen = sizeof(sockaddr6);
- nFamily = AF_INET6;
- }
+ struct sockaddr_storage sockaddr;
+#else
+ struct sockaddr sockaddr;
#endif
- else {
+ socklen_t len = sizeof(sockaddr);
+ if (!addrConnect.GetSockAddr((struct sockaddr*)&sockaddr, &len)) {
printf("Cannot connect to %s: unsupported network\n", addrConnect.ToString().c_str());
return false;
}
- SOCKET hSocket = socket(nFamily, SOCK_STREAM, IPPROTO_TCP);
+ SOCKET hSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
if (hSocket == INVALID_SOCKET)
return false;
#ifdef SO_NOSIGPIPE
@@ -369,7 +355,7 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe
return false;
}
- if (connect(hSocket, (struct sockaddr*)&sockaddr, nSockAddrLen) == SOCKET_ERROR)
+ if (connect(hSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
{
// WSAEINVAL is here because some legacy version of winsock uses it
if (WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINVAL)
@@ -902,6 +888,22 @@ CService::CService(const struct sockaddr_in6 &addr) : CNetAddr(addr.sin6_addr),
}
#endif
+bool CService::SetSockAddr(const struct sockaddr *paddr)
+{
+ switch (paddr->sa_family) {
+ case AF_INET:
+ *this = CService(*(const struct sockaddr_in*)paddr);
+ return true;
+#ifdef USE_IPV6
+ case AF_INET6:
+ *this = CService(*(const struct sockaddr_in6*)paddr);
+ return true;
+#endif
+ default:
+ return false;
+ }
+}
+
CService::CService(const char *pszIpPort, bool fAllowLookup)
{
Init();
@@ -954,29 +956,36 @@ bool operator<(const CService& a, const CService& b)
return (CNetAddr)a < (CNetAddr)b || ((CNetAddr)a == (CNetAddr)b && a.port < b.port);
}
-bool CService::GetSockAddr(struct sockaddr_in* paddr) const
+bool CService::GetSockAddr(struct sockaddr* paddr, socklen_t *addrlen) const
{
- if (!IsIPv4())
- return false;
- memset(paddr, 0, sizeof(struct sockaddr_in));
- if (!GetInAddr(&paddr->sin_addr))
- return false;
- paddr->sin_family = AF_INET;
- paddr->sin_port = htons(port);
- return true;
-}
-
+ if (IsIPv4()) {
+ if (*addrlen < sizeof(struct sockaddr_in))
+ return false;
+ *addrlen = sizeof(struct sockaddr_in);
+ struct sockaddr_in *paddrin = (struct sockaddr_in*)paddr;
+ memset(paddrin, 0, *addrlen);
+ if (!GetInAddr(&paddrin->sin_addr))
+ return false;
+ paddrin->sin_family = AF_INET;
+ paddrin->sin_port = htons(port);
+ return true;
+ }
#ifdef USE_IPV6
-bool CService::GetSockAddr6(struct sockaddr_in6* paddr) const
-{
- memset(paddr, 0, sizeof(struct sockaddr_in6));
- if (!GetIn6Addr(&paddr->sin6_addr))
- return false;
- paddr->sin6_family = AF_INET6;
- paddr->sin6_port = htons(port);
- return true;
-}
+ if (IsIPv6()) {
+ if (*addrlen < sizeof(struct sockaddr_in6))
+ return false;
+ *addrlen = sizeof(struct sockaddr_in6);
+ struct sockaddr_in6 *paddrin6 = (struct sockaddr_in6*)paddr;
+ memset(paddrin6, 0, *addrlen);
+ if (!GetIn6Addr(&paddrin6->sin6_addr))
+ return false;
+ paddrin6->sin6_family = AF_INET6;
+ paddrin6->sin6_port = htons(port);
+ return true;
+ }
#endif
+ return false;
+}
std::vector<unsigned char> CService::GetKey() const
{