Browse Source

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.
0.16
Cory Fields 8 years ago
parent
commit
2416dd7cc9
  1. 52
      src/net.cpp
  2. 4
      src/netbase.cpp
  3. 3
      src/netbase.h

52
src/net.cpp

@ -380,19 +380,16 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
pszDest ? pszDest : addrConnect.ToString(), pszDest ? pszDest : addrConnect.ToString(),
pszDest ? 0.0 : (double)(GetAdjustedTime() - addrConnect.nTime)/3600.0); pszDest ? 0.0 : (double)(GetAdjustedTime() - addrConnect.nTime)/3600.0);
// Connect // Resolve
SOCKET hSocket; const int default_port = Params().GetDefaultPort();
bool proxyConnectionFailed = false; if (pszDest) {
if (pszDest ? ConnectSocketByName(addrConnect, hSocket, pszDest, Params().GetDefaultPort(), nConnectTimeout, &proxyConnectionFailed) : std::vector<CService> resolved;
ConnectSocket(addrConnect, hSocket, nConnectTimeout, &proxyConnectionFailed)) if (Lookup(pszDest, resolved, default_port, fNameLookup && !HaveNameProxy(), 256) && !resolved.empty()) {
{ addrConnect = CAddress(resolved[GetRand(resolved.size())], NODE_NONE);
if (!IsSelectableSocket(hSocket)) { if (!addrConnect.IsValid()) {
LogPrintf("Cannot create connection: non-selectable socket created (fd >= FD_SETSIZE ?)\n"); LogPrint(BCLog::NET, "Resolver returned invalid address %s for %s", addrConnect.ToString(), pszDest);
CloseSocket(hSocket);
return nullptr; return nullptr;
} }
if (pszDest && addrConnect.IsValid()) {
// It is possible that we already have a connection to the IP/port pszDest resolved to. // 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. // 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 // 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) if (pnode)
{ {
pnode->MaybeSetAddrName(std::string(pszDest)); pnode->MaybeSetAddrName(std::string(pszDest));
CloseSocket(hSocket);
LogPrintf("Failed to open new connection, already connected\n"); LogPrintf("Failed to open new connection, already connected\n");
return nullptr; 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); 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 // Add node
NodeId id = GetNewNodeId(); NodeId id = GetNewNodeId();
@ -419,10 +443,6 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
pnode->AddRef(); pnode->AddRef();
return pnode; 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; return nullptr;

4
src/netbase.cpp

@ -399,7 +399,7 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials
return true; return true;
} }
bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRet, int nTimeout) bool ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRet, int nTimeout)
{ {
hSocketRet = INVALID_SOCKET; hSocketRet = INVALID_SOCKET;
@ -534,7 +534,7 @@ bool IsProxy(const CNetAddr &addr) {
return false; 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; SOCKET hSocket = INVALID_SOCKET;
// first connect to proxy server // first connect to proxy server

3
src/netbase.h

@ -44,6 +44,7 @@ bool GetProxy(enum Network net, proxyType &proxyInfoOut);
bool IsProxy(const CNetAddr &addr); bool IsProxy(const CNetAddr &addr);
bool SetNameProxy(const proxyType &addrProxy); bool SetNameProxy(const proxyType &addrProxy);
bool HaveNameProxy(); 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, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions, bool fAllowLookup);
bool LookupHost(const char *pszName, CNetAddr& addr, bool fAllowLookup); bool LookupHost(const char *pszName, CNetAddr& addr, bool fAllowLookup);
bool Lookup(const char *pszName, CService& addr, int portDefault, 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 LookupSubNet(const char *pszName, CSubNet& subnet);
bool ConnectSocket(const CService &addr, SOCKET& hSocketRet, int nTimeout, bool *outProxyConnectionFailed = nullptr); 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 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 */ /** Return readable error string for a network error code */
std::string NetworkErrorString(int err); std::string NetworkErrorString(int err);
/** Close socket and set hSocket to INVALID_SOCKET */ /** Close socket and set hSocket to INVALID_SOCKET */

Loading…
Cancel
Save