Skip to content

Commit 2416dd7

Browse files
committed
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.
1 parent 44e1fd9 commit 2416dd7

File tree

3 files changed

+44
-21
lines changed

3 files changed

+44
-21
lines changed

src/net.cpp

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -380,19 +380,16 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
380380
pszDest ? pszDest : addrConnect.ToString(),
381381
pszDest ? 0.0 : (double)(GetAdjustedTime() - addrConnect.nTime)/3600.0);
382382

383-
// Connect
384-
SOCKET hSocket;
385-
bool proxyConnectionFailed = false;
386-
if (pszDest ? ConnectSocketByName(addrConnect, hSocket, pszDest, Params().GetDefaultPort(), nConnectTimeout, &proxyConnectionFailed) :
387-
ConnectSocket(addrConnect, hSocket, nConnectTimeout, &proxyConnectionFailed))
388-
{
389-
if (!IsSelectableSocket(hSocket)) {
390-
LogPrintf("Cannot create connection: non-selectable socket created (fd >= FD_SETSIZE ?)\n");
391-
CloseSocket(hSocket);
392-
return nullptr;
393-
}
394-
395-
if (pszDest && addrConnect.IsValid()) {
383+
// Resolve
384+
const int default_port = Params().GetDefaultPort();
385+
if (pszDest) {
386+
std::vector<CService> resolved;
387+
if (Lookup(pszDest, resolved, default_port, fNameLookup && !HaveNameProxy(), 256) && !resolved.empty()) {
388+
addrConnect = CAddress(resolved[GetRand(resolved.size())], NODE_NONE);
389+
if (!addrConnect.IsValid()) {
390+
LogPrint(BCLog::NET, "Resolver returned invalid address %s for %s", addrConnect.ToString(), pszDest);
391+
return nullptr;
392+
}
396393
// It is possible that we already have a connection to the IP/port pszDest resolved to.
397394
// In that case, drop the connection that was just created, and return the existing CNode instead.
398395
// 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
402399
if (pnode)
403400
{
404401
pnode->MaybeSetAddrName(std::string(pszDest));
405-
CloseSocket(hSocket);
406402
LogPrintf("Failed to open new connection, already connected\n");
407403
return nullptr;
408404
}
409405
}
406+
}
410407

411-
addrman.Attempt(addrConnect, fCountFailure);
408+
// Connect
409+
bool connected = false;
410+
SOCKET hSocket;
411+
proxyType proxy;
412+
if (addrConnect.IsValid()) {
413+
bool proxyConnectionFailed = false;
414+
415+
if (GetProxy(addrConnect.GetNetwork(), proxy))
416+
connected = ConnectThroughProxy(proxy, addrConnect.ToStringIP(), addrConnect.GetPort(), hSocket, nConnectTimeout, &proxyConnectionFailed);
417+
else // no proxy needed (none set for target network)
418+
connected = ConnectSocketDirectly(addrConnect, hSocket, nConnectTimeout);
419+
if (!proxyConnectionFailed) {
420+
// If a connection to the node was attempted, and failure (if any) is not caused by a problem connecting to
421+
// the proxy, mark this as an attempt.
422+
addrman.Attempt(addrConnect, fCountFailure);
423+
}
424+
} else if (pszDest && GetNameProxy(proxy)) {
425+
std::string host;
426+
int port = default_port;
427+
SplitHostPort(std::string(pszDest), port, host);
428+
connected = ConnectThroughProxy(proxy, host, port, hSocket, nConnectTimeout, nullptr);
429+
}
430+
if (connected) {
431+
if (!IsSelectableSocket(hSocket)) {
432+
LogPrintf("Cannot create connection: non-selectable socket created (fd >= FD_SETSIZE ?)\n");
433+
CloseSocket(hSocket);
434+
return nullptr;
435+
}
412436

413437
// Add node
414438
NodeId id = GetNewNodeId();
@@ -419,10 +443,6 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
419443
pnode->AddRef();
420444

421445
return pnode;
422-
} else if (!proxyConnectionFailed) {
423-
// If connecting to the node failed, and failure is not caused by a problem connecting to
424-
// the proxy, mark this as an attempt.
425-
addrman.Attempt(addrConnect, fCountFailure);
426446
}
427447

428448
return nullptr;

src/netbase.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials
399399
return true;
400400
}
401401

402-
bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRet, int nTimeout)
402+
bool ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRet, int nTimeout)
403403
{
404404
hSocketRet = INVALID_SOCKET;
405405

@@ -534,7 +534,7 @@ bool IsProxy(const CNetAddr &addr) {
534534
return false;
535535
}
536536

537-
static bool ConnectThroughProxy(const proxyType &proxy, const std::string& strDest, int port, SOCKET& hSocketRet, int nTimeout, bool *outProxyConnectionFailed)
537+
bool ConnectThroughProxy(const proxyType &proxy, const std::string& strDest, int port, SOCKET& hSocketRet, int nTimeout, bool *outProxyConnectionFailed)
538538
{
539539
SOCKET hSocket = INVALID_SOCKET;
540540
// first connect to proxy server

src/netbase.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ bool GetProxy(enum Network net, proxyType &proxyInfoOut);
4444
bool IsProxy(const CNetAddr &addr);
4545
bool SetNameProxy(const proxyType &addrProxy);
4646
bool HaveNameProxy();
47+
bool GetNameProxy(proxyType &nameProxyOut);
4748
bool LookupHost(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions, bool fAllowLookup);
4849
bool LookupHost(const char *pszName, CNetAddr& addr, bool fAllowLookup);
4950
bool Lookup(const char *pszName, CService& addr, int portDefault, bool fAllowLookup);
@@ -52,6 +53,8 @@ CService LookupNumeric(const char *pszName, int portDefault = 0);
5253
bool LookupSubNet(const char *pszName, CSubNet& subnet);
5354
bool ConnectSocket(const CService &addr, SOCKET& hSocketRet, int nTimeout, bool *outProxyConnectionFailed = nullptr);
5455
bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest, int portDefault, int nTimeout, bool *outProxyConnectionFailed = nullptr);
56+
bool ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRet, int nTimeout);
57+
bool ConnectThroughProxy(const proxyType &proxy, const std::string& strDest, int port, SOCKET& hSocketRet, int nTimeout, bool *outProxyConnectionFailed);
5558
/** Return readable error string for a network error code */
5659
std::string NetworkErrorString(int err);
5760
/** Close socket and set hSocket to INVALID_SOCKET */

0 commit comments

Comments
 (0)