From 23aa78c405f82257e8578afb3d5d244aa27dcd74 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sat, 31 Mar 2012 17:58:25 +0200 Subject: 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. --- src/netbase.cpp | 54 +++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 11 deletions(-) (limited to 'src/netbase.cpp') 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 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 -- cgit v1.2.3