net: split socket creation out of connection
Also, check for the correct error during socket creation
This commit is contained in:
parent
6f01dcf638
commit
1729c29ded
3 changed files with 44 additions and 17 deletions
18
src/net.cpp
18
src/net.cpp
|
@ -417,16 +417,30 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
|
||||||
if (addrConnect.IsValid()) {
|
if (addrConnect.IsValid()) {
|
||||||
bool proxyConnectionFailed = false;
|
bool proxyConnectionFailed = false;
|
||||||
|
|
||||||
if (GetProxy(addrConnect.GetNetwork(), proxy))
|
if (GetProxy(addrConnect.GetNetwork(), proxy)) {
|
||||||
|
hSocket = CreateSocket(proxy.proxy);
|
||||||
|
if (hSocket == INVALID_SOCKET) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
connected = ConnectThroughProxy(proxy, addrConnect.ToStringIP(), addrConnect.GetPort(), hSocket, nConnectTimeout, &proxyConnectionFailed);
|
connected = ConnectThroughProxy(proxy, addrConnect.ToStringIP(), addrConnect.GetPort(), hSocket, nConnectTimeout, &proxyConnectionFailed);
|
||||||
else // no proxy needed (none set for target network)
|
} else {
|
||||||
|
// no proxy needed (none set for target network)
|
||||||
|
hSocket = CreateSocket(addrConnect);
|
||||||
|
if (hSocket == INVALID_SOCKET) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
connected = ConnectSocketDirectly(addrConnect, hSocket, nConnectTimeout);
|
connected = ConnectSocketDirectly(addrConnect, hSocket, nConnectTimeout);
|
||||||
|
}
|
||||||
if (!proxyConnectionFailed) {
|
if (!proxyConnectionFailed) {
|
||||||
// If a connection to the node was attempted, and failure (if any) is not caused by a problem connecting to
|
// If a connection to the node was attempted, and failure (if any) is not caused by a problem connecting to
|
||||||
// the proxy, mark this as an attempt.
|
// the proxy, mark this as an attempt.
|
||||||
addrman.Attempt(addrConnect, fCountFailure);
|
addrman.Attempt(addrConnect, fCountFailure);
|
||||||
}
|
}
|
||||||
} else if (pszDest && GetNameProxy(proxy)) {
|
} else if (pszDest && GetNameProxy(proxy)) {
|
||||||
|
hSocket = CreateSocket(proxy.proxy);
|
||||||
|
if (hSocket == INVALID_SOCKET) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
std::string host;
|
std::string host;
|
||||||
int port = default_port;
|
int port = default_port;
|
||||||
SplitHostPort(std::string(pszDest), port, host);
|
SplitHostPort(std::string(pszDest), port, host);
|
||||||
|
|
|
@ -452,20 +452,18 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRet, int nTimeout)
|
SOCKET CreateSocket(const CService &addrConnect)
|
||||||
{
|
{
|
||||||
hSocketRet = INVALID_SOCKET;
|
|
||||||
|
|
||||||
struct sockaddr_storage sockaddr;
|
struct sockaddr_storage sockaddr;
|
||||||
socklen_t len = sizeof(sockaddr);
|
socklen_t len = sizeof(sockaddr);
|
||||||
if (!addrConnect.GetSockAddr((struct sockaddr*)&sockaddr, &len)) {
|
if (!addrConnect.GetSockAddr((struct sockaddr*)&sockaddr, &len)) {
|
||||||
LogPrintf("Cannot connect to %s: unsupported network\n", addrConnect.ToString());
|
LogPrintf("Cannot create socket for %s: unsupported network\n", addrConnect.ToString());
|
||||||
return false;
|
return INVALID_SOCKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
SOCKET hSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
|
SOCKET hSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
|
||||||
if (hSocket == INVALID_SOCKET)
|
if (hSocket == INVALID_SOCKET)
|
||||||
return false;
|
return INVALID_SOCKET;
|
||||||
|
|
||||||
#ifdef SO_NOSIGPIPE
|
#ifdef SO_NOSIGPIPE
|
||||||
int set = 1;
|
int set = 1;
|
||||||
|
@ -479,9 +477,24 @@ bool ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRet, int
|
||||||
// Set to non-blocking
|
// Set to non-blocking
|
||||||
if (!SetSocketNonBlocking(hSocket, true)) {
|
if (!SetSocketNonBlocking(hSocket, true)) {
|
||||||
CloseSocket(hSocket);
|
CloseSocket(hSocket);
|
||||||
return error("ConnectSocketDirectly: Setting socket to non-blocking failed, error %s\n", NetworkErrorString(WSAGetLastError()));
|
LogPrintf("ConnectSocketDirectly: Setting socket to non-blocking failed, error %s\n", NetworkErrorString(WSAGetLastError()));
|
||||||
}
|
}
|
||||||
|
return hSocket;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocket, int nTimeout)
|
||||||
|
{
|
||||||
|
struct sockaddr_storage sockaddr;
|
||||||
|
socklen_t len = sizeof(sockaddr);
|
||||||
|
if (hSocket == INVALID_SOCKET) {
|
||||||
|
LogPrintf("Cannot connect to %s: invalid socket\n", addrConnect.ToString());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!addrConnect.GetSockAddr((struct sockaddr*)&sockaddr, &len)) {
|
||||||
|
LogPrintf("Cannot connect to %s: unsupported network\n", addrConnect.ToString());
|
||||||
|
CloseSocket(hSocket);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (connect(hSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
|
if (connect(hSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
|
||||||
{
|
{
|
||||||
int nErr = WSAGetLastError();
|
int nErr = WSAGetLastError();
|
||||||
|
@ -534,8 +547,6 @@ bool ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRet, int
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hSocketRet = hSocket;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -587,9 +598,8 @@ bool IsProxy(const CNetAddr &addr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConnectThroughProxy(const proxyType &proxy, const std::string& strDest, int port, SOCKET& hSocketRet, int nTimeout, bool *outProxyConnectionFailed)
|
bool ConnectThroughProxy(const proxyType &proxy, const std::string& strDest, int port, SOCKET& hSocket, int nTimeout, bool *outProxyConnectionFailed)
|
||||||
{
|
{
|
||||||
SOCKET hSocket = INVALID_SOCKET;
|
|
||||||
// first connect to proxy server
|
// first connect to proxy server
|
||||||
if (!ConnectSocketDirectly(proxy.proxy, hSocket, nTimeout)) {
|
if (!ConnectSocketDirectly(proxy.proxy, hSocket, nTimeout)) {
|
||||||
if (outProxyConnectionFailed)
|
if (outProxyConnectionFailed)
|
||||||
|
@ -601,14 +611,16 @@ bool ConnectThroughProxy(const proxyType &proxy, const std::string& strDest, int
|
||||||
ProxyCredentials random_auth;
|
ProxyCredentials random_auth;
|
||||||
static std::atomic_int counter(0);
|
static std::atomic_int counter(0);
|
||||||
random_auth.username = random_auth.password = strprintf("%i", counter++);
|
random_auth.username = random_auth.password = strprintf("%i", counter++);
|
||||||
if (!Socks5(strDest, (unsigned short)port, &random_auth, hSocket))
|
if (!Socks5(strDest, (unsigned short)port, &random_auth, hSocket)) {
|
||||||
|
CloseSocket(hSocket);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!Socks5(strDest, (unsigned short)port, 0, hSocket))
|
if (!Socks5(strDest, (unsigned short)port, 0, hSocket)) {
|
||||||
|
CloseSocket(hSocket);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hSocketRet = hSocket;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool LookupSubNet(const char* pszName, CSubNet& ret)
|
bool LookupSubNet(const char* pszName, CSubNet& ret)
|
||||||
|
|
|
@ -51,6 +51,7 @@ bool Lookup(const char *pszName, CService& addr, int portDefault, bool fAllowLoo
|
||||||
bool Lookup(const char *pszName, std::vector<CService>& vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions);
|
bool Lookup(const char *pszName, std::vector<CService>& vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions);
|
||||||
CService LookupNumeric(const char *pszName, int portDefault = 0);
|
CService LookupNumeric(const char *pszName, int portDefault = 0);
|
||||||
bool LookupSubNet(const char *pszName, CSubNet& subnet);
|
bool LookupSubNet(const char *pszName, CSubNet& subnet);
|
||||||
|
SOCKET CreateSocket(const CService &addrConnect);
|
||||||
bool ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRet, int nTimeout);
|
bool ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRet, int nTimeout);
|
||||||
bool ConnectThroughProxy(const proxyType &proxy, const std::string& strDest, int port, SOCKET& hSocketRet, int nTimeout, bool *outProxyConnectionFailed);
|
bool ConnectThroughProxy(const proxyType &proxy, const std::string& strDest, int port, SOCKET& hSocketRet, int nTimeout, bool *outProxyConnectionFailed);
|
||||||
/** Return readable error string for a network error code */
|
/** Return readable error string for a network error code */
|
||||||
|
|
Loading…
Add table
Reference in a new issue