Changeset View
Changeset View
Standalone View
Standalone View
src/netbase.cpp
// Copyright (c) 2009-2010 Satoshi Nakamoto | // Copyright (c) 2009-2010 Satoshi Nakamoto | ||||
// Copyright (c) 2009-2016 The Bitcoin Core developers | // Copyright (c) 2009-2016 The Bitcoin Core developers | ||||
// Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
#include <netbase.h> | #include <netbase.h> | ||||
#include <hash.h> | #include <hash.h> | ||||
#include <random.h> | #include <random.h> | ||||
#include <sync.h> | #include <sync.h> | ||||
#include <uint256.h> | #include <uint256.h> | ||||
#include <util.h> | #include <util.h> | ||||
#include <utilstrencodings.h> | #include <utilstrencodings.h> | ||||
#include <tinyformat.h> | |||||
#include <atomic> | #include <atomic> | ||||
#ifndef WIN32 | #ifndef WIN32 | ||||
#include <fcntl.h> | #include <fcntl.h> | ||||
#endif | #endif | ||||
#if !defined(MSG_NOSIGNAL) | #if !defined(MSG_NOSIGNAL) | ||||
#define MSG_NOSIGNAL 0 | #define MSG_NOSIGNAL 0 | ||||
▲ Show 20 Lines • Show All 494 Lines • ▼ Show 20 Lines | if (!SetSocketNonBlocking(hSocket, true)) { | ||||
CloseSocket(hSocket); | CloseSocket(hSocket); | ||||
LogPrintf("ConnectSocketDirectly: Setting socket to non-blocking " | LogPrintf("ConnectSocketDirectly: Setting socket to non-blocking " | ||||
"failed, error %s\n", | "failed, error %s\n", | ||||
NetworkErrorString(WSAGetLastError())); | NetworkErrorString(WSAGetLastError())); | ||||
} | } | ||||
return hSocket; | return hSocket; | ||||
} | } | ||||
template <typename... Args> | |||||
static void LogConnectFailure(bool manual_connection, const char *fmt, | |||||
const Args &... args) { | |||||
std::string error_message = tfm::format(fmt, args...); | |||||
if (manual_connection) { | |||||
LogPrintf("%s\n", error_message); | |||||
} else { | |||||
LogPrint(BCLog::NET, "%s\n", error_message); | |||||
} | |||||
} | |||||
bool ConnectSocketDirectly(const CService &addrConnect, const SOCKET &hSocket, | bool ConnectSocketDirectly(const CService &addrConnect, const SOCKET &hSocket, | ||||
int nTimeout) { | int nTimeout, bool manual_connection) { | ||||
struct sockaddr_storage sockaddr; | struct sockaddr_storage sockaddr; | ||||
socklen_t len = sizeof(sockaddr); | socklen_t len = sizeof(sockaddr); | ||||
if (hSocket == INVALID_SOCKET) { | if (hSocket == INVALID_SOCKET) { | ||||
LogPrintf("Cannot connect to %s: invalid socket\n", | LogPrintf("Cannot connect to %s: invalid socket\n", | ||||
addrConnect.ToString()); | addrConnect.ToString()); | ||||
return false; | return false; | ||||
} | } | ||||
if (!addrConnect.GetSockAddr((struct sockaddr *)&sockaddr, &len)) { | if (!addrConnect.GetSockAddr((struct sockaddr *)&sockaddr, &len)) { | ||||
Show All 27 Lines | if (connect(hSocket, (struct sockaddr *)&sockaddr, len) == SOCKET_ERROR) { | ||||
(sockopt_arg_type)&nRet, | (sockopt_arg_type)&nRet, | ||||
&nRetSize) == SOCKET_ERROR) { | &nRetSize) == SOCKET_ERROR) { | ||||
LogPrintf("getsockopt() for %s failed: %s\n", | LogPrintf("getsockopt() for %s failed: %s\n", | ||||
addrConnect.ToString(), | addrConnect.ToString(), | ||||
NetworkErrorString(WSAGetLastError())); | NetworkErrorString(WSAGetLastError())); | ||||
return false; | return false; | ||||
} | } | ||||
if (nRet != 0) { | if (nRet != 0) { | ||||
LogPrintf("connect() to %s failed after select(): %s\n", | LogConnectFailure(manual_connection, | ||||
addrConnect.ToString(), NetworkErrorString(nRet)); | "connect() to %s failed after select(): %s", | ||||
addrConnect.ToString(), | |||||
NetworkErrorString(nRet)); | |||||
return false; | return false; | ||||
} | } | ||||
} | } | ||||
#ifdef WIN32 | #ifdef WIN32 | ||||
else if (WSAGetLastError() != WSAEISCONN) | else if (WSAGetLastError() != WSAEISCONN) | ||||
#else | #else | ||||
else | else | ||||
#endif | #endif | ||||
{ | { | ||||
LogPrintf("connect() to %s failed: %s\n", addrConnect.ToString(), | LogConnectFailure(manual_connection, "connect() to %s failed: %s", | ||||
addrConnect.ToString(), | |||||
NetworkErrorString(WSAGetLastError())); | NetworkErrorString(WSAGetLastError())); | ||||
return false; | return false; | ||||
} | } | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
bool SetProxy(enum Network net, const proxyType &addrProxy) { | bool SetProxy(enum Network net, const proxyType &addrProxy) { | ||||
assert(net >= 0 && net < NET_MAX); | assert(net >= 0 && net < NET_MAX); | ||||
▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | bool IsProxy(const CNetAddr &addr) { | ||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
bool ConnectThroughProxy(const proxyType &proxy, const std::string &strDest, | bool ConnectThroughProxy(const proxyType &proxy, const std::string &strDest, | ||||
int port, const SOCKET &hSocket, int nTimeout, | int port, const SOCKET &hSocket, int nTimeout, | ||||
bool *outProxyConnectionFailed) { | bool *outProxyConnectionFailed) { | ||||
// first connect to proxy server | // first connect to proxy server | ||||
if (!ConnectSocketDirectly(proxy.proxy, hSocket, nTimeout)) { | if (!ConnectSocketDirectly(proxy.proxy, hSocket, nTimeout, true)) { | ||||
if (outProxyConnectionFailed) { | if (outProxyConnectionFailed) { | ||||
*outProxyConnectionFailed = true; | *outProxyConnectionFailed = true; | ||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
// do socks negotiation | // do socks negotiation | ||||
if (proxy.randomize_credentials) { | if (proxy.randomize_credentials) { | ||||
ProxyCredentials random_auth; | ProxyCredentials random_auth; | ||||
static std::atomic_int counter(0); | static std::atomic_int counter(0); | ||||
random_auth.username = random_auth.password = | random_auth.username = random_auth.password = | ||||
strprintf("%i", counter++); | strprintf("%i", counter++); | ||||
if (!Socks5(strDest, (unsigned short)port, &random_auth, hSocket)) { | if (!Socks5(strDest, (unsigned short)port, &random_auth, hSocket)) { | ||||
return false; | return false; | ||||
} | } | ||||
} else if (!Socks5(strDest, (unsigned short)port, 0, hSocket)) { | } else if (!Socks5(strDest, (unsigned short)port, 0, hSocket)) { | ||||
return false; | return false; | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
bool LookupSubNet(const char *pszName, CSubNet &ret) { | bool LookupSubNet(const char *pszName, CSubNet &ret) { | ||||
std::string strSubnet(pszName); | std::string strSubnet(pszName); | ||||
size_t slash = strSubnet.find_last_of('/'); | size_t slash = strSubnet.find_last_of('/'); | ||||
std::vector<CNetAddr> vIP; | std::vector<CNetAddr> vIP; | ||||
std::string strAddress = strSubnet.substr(0, slash); | std::string strAddress = strSubnet.substr(0, slash); | ||||
if (LookupHost(strAddress.c_str(), vIP, 1, false)) { | if (LookupHost(strAddress.c_str(), vIP, 1, false)) { | ||||
CNetAddr network = vIP[0]; | CNetAddr network = vIP[0]; | ||||
▲ Show 20 Lines • Show All 115 Lines • Show Last 20 Lines |