Mercurial > hg > bitcoin
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(); |