aboutsummaryrefslogtreecommitdiff
path: root/src/netbase.cpp
diff options
context:
space:
mode:
authorPieter Wuille <pieter.wuille@gmail.com>2012-03-31 17:58:25 +0200
committerPieter Wuille <pieter.wuille@gmail.com>2012-05-11 15:29:19 +0200
commit23aa78c405f82257e8578afb3d5d244aa27dcd74 (patch)
tree27e99a7b7ef6c3f9d178e394b8ef630bbef852f3 /src/netbase.cpp
parent508471bbc0b43a8d5cabeae5c429f8416b9a1e99 (diff)
IPv6 node support
This will make bitcoin relay valid routable IPv6 addresses, and when USE_IPV6 is enabled, listen on IPv6 interfaces and attempt connections to IPv6 addresses.
Diffstat (limited to 'src/netbase.cpp')
-rw-r--r--src/netbase.cpp54
1 files changed, 43 insertions, 11 deletions
diff --git a/src/netbase.cpp b/src/netbase.cpp
index 48709dc5c6..a22d42a967 100644
--- a/src/netbase.cpp
+++ b/src/netbase.cpp
@@ -305,7 +305,37 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe
{
hSocketRet = INVALID_SOCKET;
- SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ 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;
+ }
+#endif
+ else {
+ printf("Cannot connect to %s: unsupported network\n", addrConnect.ToString().c_str());
+ return false;
+ }
+
+ SOCKET hSocket = socket(nFamily, SOCK_STREAM, IPPROTO_TCP);
if (hSocket == INVALID_SOCKET)
return false;
#ifdef SO_NOSIGPIPE
@@ -313,13 +343,6 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe
setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
#endif
- struct sockaddr_in sockaddr;
- if (!addrConnect.GetSockAddr(&sockaddr))
- {
- closesocket(hSocket);
- return false;
- }
-
#ifdef WIN32
u_long fNonblock = 1;
if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR)
@@ -332,7 +355,7 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe
return false;
}
- if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
+ if (connect(hSocket, (struct sockaddr*)&sockaddr, nSockAddrLen) == SOCKET_ERROR)
{
// WSAEINVAL is here because some legacy version of winsock uses it
if (WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINVAL)
@@ -531,6 +554,11 @@ bool CNetAddr::IsIPv4() const
return (memcmp(ip, pchIPv4, sizeof(pchIPv4)) == 0);
}
+bool CNetAddr::IsIPv6() const
+{
+ return (!IsIPv4());
+}
+
bool CNetAddr::IsRFC1918() const
{
return IsIPv4() && (
@@ -919,12 +947,16 @@ std::vector<unsigned char> CService::GetKey() const
std::string CService::ToStringPort() const
{
- return strprintf(":%i", port);
+ return strprintf("%i", port);
}
std::string CService::ToStringIPPort() const
{
- return ToStringIP() + ToStringPort();
+ if (IsIPv4()) {
+ return ToStringIP() + ":" + ToStringPort();
+ } else {
+ return "[" + ToStringIP() + "]:" + ToStringPort();
+ }
}
std::string CService::ToString() const