aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/net.cpp58
-rw-r--r--src/netbase.cpp4
-rw-r--r--src/netbase.h3
3 files changed, 44 insertions, 21 deletions
diff --git a/src/net.cpp b/src/net.cpp
index 587c9e5110..a9f26fb566 100644
--- a/src/net.cpp
+++ b/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);
- return nullptr;
- }
-
- if (pszDest && addrConnect.IsValid()) {
+ // 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;
+ }
// 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;
}
}
+ }
- addrman.Attempt(addrConnect, fCountFailure);
+ // 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;
diff --git a/src/netbase.cpp b/src/netbase.cpp
index 05f9f6961c..d4a91da1f0 100644
--- a/src/netbase.cpp
+++ b/src/netbase.cpp
@@ -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
diff --git a/src/netbase.h b/src/netbase.h
index 6572f0a12e..50425f0f80 100644
--- a/src/netbase.h
+++ b/src/netbase.h
@@ -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 */