net: separate resolving and conecting
ConnectSocketByName handled resolves as necessary, obscuring the connection process. With them separated, each can be handled asynchronously. Also, since proxies must be considered now anyway, go ahead and eliminate the ConnectSocket wrapper and use ConnectSocketDirectly... directly.
This commit is contained in:
parent
44e1fd926c
commit
2416dd7cc9
3 changed files with 44 additions and 21 deletions
52
src/net.cpp
52
src/net.cpp
|
@ -380,19 +380,16 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
|
|||
pszDest ? pszDest : addrConnect.ToString(),
|
||||
pszDest ? 0.0 : (double)(GetAdjustedTime() - addrConnect.nTime)/3600.0);
|
||||
|
||||
// Connect
|
||||
SOCKET hSocket;
|
||||
bool proxyConnectionFailed = false;
|
||||
if (pszDest ? ConnectSocketByName(addrConnect, hSocket, pszDest, Params().GetDefaultPort(), nConnectTimeout, &proxyConnectionFailed) :
|
||||
ConnectSocket(addrConnect, hSocket, nConnectTimeout, &proxyConnectionFailed))
|
||||
{
|
||||
if (!IsSelectableSocket(hSocket)) {
|
||||
LogPrintf("Cannot create connection: non-selectable socket created (fd >= FD_SETSIZE ?)\n");
|
||||
CloseSocket(hSocket);
|
||||
// Resolve
|
||||
const int default_port = Params().GetDefaultPort();
|
||||
if (pszDest) {
|
||||
std::vector<CService> resolved;
|
||||
if (Lookup(pszDest, resolved, default_port, fNameLookup && !HaveNameProxy(), 256) && !resolved.empty()) {
|
||||
addrConnect = CAddress(resolved[GetRand(resolved.size())], NODE_NONE);
|
||||
if (!addrConnect.IsValid()) {
|
||||
LogPrint(BCLog::NET, "Resolver returned invalid address %s for %s", addrConnect.ToString(), pszDest);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (pszDest && addrConnect.IsValid()) {
|
||||
// It is possible that we already have a connection to the IP/port pszDest resolved to.
|
||||
// In that case, drop the connection that was just created, and return the existing CNode instead.
|
||||
// Also store the name we used to connect in that CNode, so that future FindNode() calls to that
|
||||
|
@ -402,13 +399,40 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
|
|||
if (pnode)
|
||||
{
|
||||
pnode->MaybeSetAddrName(std::string(pszDest));
|
||||
CloseSocket(hSocket);
|
||||
LogPrintf("Failed to open new connection, already connected\n");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Connect
|
||||
bool connected = false;
|
||||
SOCKET hSocket;
|
||||
proxyType proxy;
|
||||
if (addrConnect.IsValid()) {
|
||||
bool proxyConnectionFailed = false;
|
||||
|
||||
if (GetProxy(addrConnect.GetNetwork(), proxy))
|
||||
connected = ConnectThroughProxy(proxy, addrConnect.ToStringIP(), addrConnect.GetPort(), hSocket, nConnectTimeout, &proxyConnectionFailed);
|
||||
else // no proxy needed (none set for target network)
|
||||
connected = ConnectSocketDirectly(addrConnect, hSocket, nConnectTimeout);
|
||||
if (!proxyConnectionFailed) {
|
||||
// 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.
|
||||
addrman.Attempt(addrConnect, fCountFailure);
|
||||
}
|
||||
} else if (pszDest && GetNameProxy(proxy)) {
|
||||
std::string host;
|
||||
int port = default_port;
|
||||
SplitHostPort(std::string(pszDest), port, host);
|
||||
connected = ConnectThroughProxy(proxy, host, port, hSocket, nConnectTimeout, nullptr);
|
||||
}
|
||||
if (connected) {
|
||||
if (!IsSelectableSocket(hSocket)) {
|
||||
LogPrintf("Cannot create connection: non-selectable socket created (fd >= FD_SETSIZE ?)\n");
|
||||
CloseSocket(hSocket);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Add node
|
||||
NodeId id = GetNewNodeId();
|
||||
|
@ -419,10 +443,6 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
|
|||
pnode->AddRef();
|
||||
|
||||
return pnode;
|
||||
} else if (!proxyConnectionFailed) {
|
||||
// If connecting to the node failed, and failure is not caused by a problem connecting to
|
||||
// the proxy, mark this as an attempt.
|
||||
addrman.Attempt(addrConnect, fCountFailure);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
|
|
@ -399,7 +399,7 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials
|
|||
return true;
|
||||
}
|
||||
|
||||
bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRet, int nTimeout)
|
||||
bool ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRet, int nTimeout)
|
||||
{
|
||||
hSocketRet = INVALID_SOCKET;
|
||||
|
||||
|
@ -534,7 +534,7 @@ bool IsProxy(const CNetAddr &addr) {
|
|||
return false;
|
||||
}
|
||||
|
||||
static 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)
|
||||
{
|
||||
SOCKET hSocket = INVALID_SOCKET;
|
||||
// first connect to proxy server
|
||||
|
|
|
@ -44,6 +44,7 @@ bool GetProxy(enum Network net, proxyType &proxyInfoOut);
|
|||
bool IsProxy(const CNetAddr &addr);
|
||||
bool SetNameProxy(const proxyType &addrProxy);
|
||||
bool HaveNameProxy();
|
||||
bool GetNameProxy(proxyType &nameProxyOut);
|
||||
bool LookupHost(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions, bool fAllowLookup);
|
||||
bool LookupHost(const char *pszName, CNetAddr& addr, bool fAllowLookup);
|
||||
bool Lookup(const char *pszName, CService& addr, int portDefault, bool fAllowLookup);
|
||||
|
@ -52,6 +53,8 @@ CService LookupNumeric(const char *pszName, int portDefault = 0);
|
|||
bool LookupSubNet(const char *pszName, CSubNet& subnet);
|
||||
bool ConnectSocket(const CService &addr, SOCKET& hSocketRet, int nTimeout, bool *outProxyConnectionFailed = nullptr);
|
||||
bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest, int portDefault, int nTimeout, bool *outProxyConnectionFailed = nullptr);
|
||||
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);
|
||||
/** Return readable error string for a network error code */
|
||||
std::string NetworkErrorString(int err);
|
||||
/** Close socket and set hSocket to INVALID_SOCKET */
|
||||
|
|
Loading…
Reference in a new issue