diff src/netbase.cpp @ 2476:a9b012461972 draft

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.
author Pieter Wuille <pieter.wuille@gmail.com>
date Sat, 31 Mar 2012 17:58:25 +0200
parents 1f0e9f9f3e51
children f8e75c9db98a
line wrap: on
line diff
--- a/src/netbase.cpp
+++ b/src/netbase.cpp
@@ -305,7 +305,37 @@
 {
     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 @@
     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 @@
         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 @@
     return (memcmp(ip, pchIPv4, sizeof(pchIPv4)) == 0);
 }
 
+bool CNetAddr::IsIPv6() const
+{
+    return (!IsIPv4());
+}
+
 bool CNetAddr::IsRFC1918() const
 {
     return IsIPv4() && (
@@ -919,12 +947,16 @@
 
 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