Skip to content

Commit 9d31ed2

Browse files
committed
Merge #10663: net: split resolve out of connect
b887676 net: remove now-unused functions (Cory Fields) 45fd754 net: remove now-superfluous numeric resolve (Cory Fields) 2416dd7 net: separate resolving and conecting (Cory Fields) Pull request description: This is a greatly simplified version of #10285, which only aims to address async resolving. It essentially breaks up two wrapper functions for things only used in one place (ConnectSocketDirectly/ConnectThroughProxy) in favor of calling them directly. This allows us to fully handle resolves before attempting a connection, as is necessary for async connections. As a bonus, I believe the logic is now much easier to follow than before. Tree-SHA512: f03f618107379edf3efe2a9f3e3677e8f075017ab140a0b4fdc3b8263e6beff148d55256263ab10bc2125ef089ca68e0d8e865beeae176f1eca544e769c976d3
2 parents 9a8e916 + b887676 commit 9d31ed2

File tree

3 files changed

+46
-68
lines changed

3 files changed

+46
-68
lines changed

src/net.cpp

Lines changed: 41 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -385,19 +385,16 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
385385
pszDest ? pszDest : addrConnect.ToString(),
386386
pszDest ? 0.0 : (double)(GetAdjustedTime() - addrConnect.nTime)/3600.0);
387387

388-
// Connect
389-
SOCKET hSocket;
390-
bool proxyConnectionFailed = false;
391-
if (pszDest ? ConnectSocketByName(addrConnect, hSocket, pszDest, Params().GetDefaultPort(), nConnectTimeout, &proxyConnectionFailed) :
392-
ConnectSocket(addrConnect, hSocket, nConnectTimeout, &proxyConnectionFailed))
393-
{
394-
if (!IsSelectableSocket(hSocket)) {
395-
LogPrintf("Cannot create connection: non-selectable socket created (fd >= FD_SETSIZE ?)\n");
396-
CloseSocket(hSocket);
397-
return nullptr;
398-
}
399-
400-
if (pszDest && addrConnect.IsValid()) {
388+
// Resolve
389+
const int default_port = Params().GetDefaultPort();
390+
if (pszDest) {
391+
std::vector<CService> resolved;
392+
if (Lookup(pszDest, resolved, default_port, fNameLookup && !HaveNameProxy(), 256) && !resolved.empty()) {
393+
addrConnect = CAddress(resolved[GetRand(resolved.size())], NODE_NONE);
394+
if (!addrConnect.IsValid()) {
395+
LogPrint(BCLog::NET, "Resolver returned invalid address %s for %s", addrConnect.ToString(), pszDest);
396+
return nullptr;
397+
}
401398
// It is possible that we already have a connection to the IP/port pszDest resolved to.
402399
// In that case, drop the connection that was just created, and return the existing CNode instead.
403400
// Also store the name we used to connect in that CNode, so that future FindNode() calls to that
@@ -407,13 +404,40 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
407404
if (pnode)
408405
{
409406
pnode->MaybeSetAddrName(std::string(pszDest));
410-
CloseSocket(hSocket);
411407
LogPrintf("Failed to open new connection, already connected\n");
412408
return nullptr;
413409
}
414410
}
411+
}
415412

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

418442
// Add node
419443
NodeId id = GetNewNodeId();
@@ -424,10 +448,6 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
424448
pnode->AddRef();
425449

426450
return pnode;
427-
} else if (!proxyConnectionFailed) {
428-
// If connecting to the node failed, and failure is not caused by a problem connecting to
429-
// the proxy, mark this as an attempt.
430-
addrman.Attempt(addrConnect, fCountFailure);
431451
}
432452

433453
return nullptr;
@@ -1912,11 +1932,9 @@ void CConnman::ThreadOpenAddedConnections()
19121932
// the addednodeinfo state might change.
19131933
break;
19141934
}
1915-
// If strAddedNode is an IP/port, decode it immediately, so
1916-
// OpenNetworkConnection can detect existing connections to that IP/port.
19171935
tried = true;
1918-
CService service(LookupNumeric(info.strAddedNode.c_str(), Params().GetDefaultPort()));
1919-
OpenNetworkConnection(CAddress(service, NODE_NONE), false, &grant, info.strAddedNode.c_str(), false, false, true);
1936+
CAddress addr(CService(), NODE_NONE);
1937+
OpenNetworkConnection(addr, false, &grant, info.strAddedNode.c_str(), false, false, true);
19201938
if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
19211939
return;
19221940
}

src/netbase.cpp

Lines changed: 2 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,7 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials
452452
return true;
453453
}
454454

455-
bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRet, int nTimeout)
455+
bool ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRet, int nTimeout)
456456
{
457457
hSocketRet = INVALID_SOCKET;
458458

@@ -587,7 +587,7 @@ bool IsProxy(const CNetAddr &addr) {
587587
return false;
588588
}
589589

590-
static bool ConnectThroughProxy(const proxyType &proxy, const std::string& strDest, int port, SOCKET& hSocketRet, int nTimeout, bool *outProxyConnectionFailed)
590+
bool ConnectThroughProxy(const proxyType &proxy, const std::string& strDest, int port, SOCKET& hSocketRet, int nTimeout, bool *outProxyConnectionFailed)
591591
{
592592
SOCKET hSocket = INVALID_SOCKET;
593593
// first connect to proxy server
@@ -611,47 +611,6 @@ static bool ConnectThroughProxy(const proxyType &proxy, const std::string& strDe
611611
hSocketRet = hSocket;
612612
return true;
613613
}
614-
615-
bool ConnectSocket(const CService &addrDest, SOCKET& hSocketRet, int nTimeout, bool *outProxyConnectionFailed)
616-
{
617-
proxyType proxy;
618-
if (outProxyConnectionFailed)
619-
*outProxyConnectionFailed = false;
620-
621-
if (GetProxy(addrDest.GetNetwork(), proxy))
622-
return ConnectThroughProxy(proxy, addrDest.ToStringIP(), addrDest.GetPort(), hSocketRet, nTimeout, outProxyConnectionFailed);
623-
else // no proxy needed (none set for target network)
624-
return ConnectSocketDirectly(addrDest, hSocketRet, nTimeout);
625-
}
626-
627-
bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest, int portDefault, int nTimeout, bool *outProxyConnectionFailed)
628-
{
629-
std::string strDest;
630-
int port = portDefault;
631-
632-
if (outProxyConnectionFailed)
633-
*outProxyConnectionFailed = false;
634-
635-
SplitHostPort(std::string(pszDest), port, strDest);
636-
637-
proxyType proxy;
638-
GetNameProxy(proxy);
639-
640-
std::vector<CService> addrResolved;
641-
if (Lookup(strDest.c_str(), addrResolved, port, fNameLookup && !HaveNameProxy(), 256)) {
642-
if (addrResolved.size() > 0) {
643-
addr = addrResolved[GetRand(addrResolved.size())];
644-
return ConnectSocket(addr, hSocketRet, nTimeout);
645-
}
646-
}
647-
648-
addr = CService();
649-
650-
if (!HaveNameProxy())
651-
return false;
652-
return ConnectThroughProxy(proxy, strDest, port, hSocketRet, nTimeout, outProxyConnectionFailed);
653-
}
654-
655614
bool LookupSubNet(const char* pszName, CSubNet& ret)
656615
{
657616
std::string strSubnet(pszName);

src/netbase.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,15 @@ 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);
5051
bool Lookup(const char *pszName, std::vector<CService>& vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions);
5152
CService LookupNumeric(const char *pszName, int portDefault = 0);
5253
bool LookupSubNet(const char *pszName, CSubNet& subnet);
53-
bool ConnectSocket(const CService &addr, SOCKET& hSocketRet, int nTimeout, bool *outProxyConnectionFailed = nullptr);
54-
bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest, int portDefault, int nTimeout, bool *outProxyConnectionFailed = nullptr);
54+
bool ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRet, int nTimeout);
55+
bool ConnectThroughProxy(const proxyType &proxy, const std::string& strDest, int port, SOCKET& hSocketRet, int nTimeout, bool *outProxyConnectionFailed);
5556
/** Return readable error string for a network error code */
5657
std::string NetworkErrorString(int err);
5758
/** Close socket and set hSocket to INVALID_SOCKET */

0 commit comments

Comments
 (0)