comparison 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
comparison
equal deleted inserted replaced
2466:c5898fd4a4f5 2476:a9b012461972
303 303
304 bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRet, int nTimeout) 304 bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRet, int nTimeout)
305 { 305 {
306 hSocketRet = INVALID_SOCKET; 306 hSocketRet = INVALID_SOCKET;
307 307
308 SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 308 struct sockaddr_storage sockaddr;
309 int nFamily = 0;
310 size_t nSockAddrLen = 0;
311
312 if (addrConnect.IsIPv4())
313 {
314 // Use IPv4 stack to connect to IPv4 addresses
315 struct sockaddr_in sockaddr4;
316 if (!addrConnect.GetSockAddr(&sockaddr4))
317 return false;
318 memcpy(&sockaddr, &sockaddr4, sizeof(sockaddr4));
319 nSockAddrLen = sizeof(sockaddr4);
320 nFamily = AF_INET;
321 }
322 #ifdef USE_IPV6
323 else if (addrConnect.IsIPv6())
324 {
325 struct sockaddr_in6 sockaddr6;
326 if (!addrConnect.GetSockAddr6(&sockaddr6))
327 return false;
328 memcpy(&sockaddr, &sockaddr6, sizeof(sockaddr6));
329 nSockAddrLen = sizeof(sockaddr6);
330 nFamily = AF_INET6;
331 }
332 #endif
333 else {
334 printf("Cannot connect to %s: unsupported network\n", addrConnect.ToString().c_str());
335 return false;
336 }
337
338 SOCKET hSocket = socket(nFamily, SOCK_STREAM, IPPROTO_TCP);
309 if (hSocket == INVALID_SOCKET) 339 if (hSocket == INVALID_SOCKET)
310 return false; 340 return false;
311 #ifdef SO_NOSIGPIPE 341 #ifdef SO_NOSIGPIPE
312 int set = 1; 342 int set = 1;
313 setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int)); 343 setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
314 #endif 344 #endif
315
316 struct sockaddr_in sockaddr;
317 if (!addrConnect.GetSockAddr(&sockaddr))
318 {
319 closesocket(hSocket);
320 return false;
321 }
322 345
323 #ifdef WIN32 346 #ifdef WIN32
324 u_long fNonblock = 1; 347 u_long fNonblock = 1;
325 if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR) 348 if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR)
326 #else 349 #else
330 { 353 {
331 closesocket(hSocket); 354 closesocket(hSocket);
332 return false; 355 return false;
333 } 356 }
334 357
335 if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR) 358 if (connect(hSocket, (struct sockaddr*)&sockaddr, nSockAddrLen) == SOCKET_ERROR)
336 { 359 {
337 // WSAEINVAL is here because some legacy version of winsock uses it 360 // WSAEINVAL is here because some legacy version of winsock uses it
338 if (WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINVAL) 361 if (WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINVAL)
339 { 362 {
340 struct timeval timeout; 363 struct timeval timeout;
529 bool CNetAddr::IsIPv4() const 552 bool CNetAddr::IsIPv4() const
530 { 553 {
531 return (memcmp(ip, pchIPv4, sizeof(pchIPv4)) == 0); 554 return (memcmp(ip, pchIPv4, sizeof(pchIPv4)) == 0);
532 } 555 }
533 556
557 bool CNetAddr::IsIPv6() const
558 {
559 return (!IsIPv4());
560 }
561
534 bool CNetAddr::IsRFC1918() const 562 bool CNetAddr::IsRFC1918() const
535 { 563 {
536 return IsIPv4() && ( 564 return IsIPv4() && (
537 GetByte(3) == 10 || 565 GetByte(3) == 10 ||
538 (GetByte(3) == 192 && GetByte(2) == 168) || 566 (GetByte(3) == 192 && GetByte(2) == 168) ||
917 return vKey; 945 return vKey;
918 } 946 }
919 947
920 std::string CService::ToStringPort() const 948 std::string CService::ToStringPort() const
921 { 949 {
922 return strprintf(":%i", port); 950 return strprintf("%i", port);
923 } 951 }
924 952
925 std::string CService::ToStringIPPort() const 953 std::string CService::ToStringIPPort() const
926 { 954 {
927 return ToStringIP() + ToStringPort(); 955 if (IsIPv4()) {
956 return ToStringIP() + ":" + ToStringPort();
957 } else {
958 return "[" + ToStringIP() + "]:" + ToStringPort();
959 }
928 } 960 }
929 961
930 std::string CService::ToString() const 962 std::string CService::ToString() const
931 { 963 {
932 return ToStringIPPort(); 964 return ToStringIPPort();