| 368 | } |
| 369 | |
| 370 | CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, bool manual_connection) |
| 371 | { |
| 372 | if (pszDest == nullptr) { |
| 373 | if (IsLocal(addrConnect)) |
| 374 | return nullptr; |
| 375 | |
| 376 | // Look for an existing connection |
| 377 | CNode* pnode = FindNode(static_cast<CService>(addrConnect)); |
| 378 | if (pnode) |
| 379 | { |
| 380 | LogPrintf("Failed to open new connection, already connected\n"); |
| 381 | return nullptr; |
| 382 | } |
| 383 | } |
| 384 | |
| 385 | /// debug print |
| 386 | LogPrint(BCLog::NET, "trying connection %s lastseen=%.1fhrs\n", |
| 387 | pszDest ? pszDest : addrConnect.ToString(), |
| 388 | pszDest ? 0.0 : (double)(GetAdjustedTime() - addrConnect.nTime)/3600.0); |
| 389 | |
| 390 | // Resolve |
| 391 | const int default_port = Params().GetDefaultPort(); |
| 392 | if (pszDest) { |
| 393 | std::vector<CService> resolved; |
| 394 | if (Lookup(pszDest, resolved, default_port, fNameLookup && !HaveNameProxy(), 256) && !resolved.empty()) { |
| 395 | addrConnect = CAddress(resolved[GetRand(resolved.size())], NODE_NONE); |
| 396 | if (!addrConnect.IsValid()) { |
| 397 | LogPrint(BCLog::NET, "Resolver returned invalid address %s for %s\n", addrConnect.ToString(), pszDest); |
| 398 | return nullptr; |
| 399 | } |
| 400 | // It is possible that we already have a connection to the IP/port pszDest resolved to. |
| 401 | // In that case, drop the connection that was just created, and return the existing CNode instead. |
| 402 | // Also store the name we used to connect in that CNode, so that future FindNode() calls to that |
| 403 | // name catch this early. |
| 404 | LOCK(cs_vNodes); |
| 405 | CNode* pnode = FindNode(static_cast<CService>(addrConnect)); |
| 406 | if (pnode) |
| 407 | { |
| 408 | pnode->MaybeSetAddrName(std::string(pszDest)); |
| 409 | LogPrintf("Failed to open new connection, already connected\n"); |
| 410 | return nullptr; |
| 411 | } |
| 412 | } |
| 413 | } |
| 414 | |
| 415 | // Connect |
| 416 | bool connected = false; |
| 417 | SOCKET hSocket = INVALID_SOCKET; |
| 418 | proxyType proxy; |
| 419 | if (addrConnect.IsValid()) { |
| 420 | bool proxyConnectionFailed = false; |
| 421 | |
| 422 | if (GetProxy(addrConnect.GetNetwork(), proxy)) { |
| 423 | hSocket = CreateSocket(proxy.proxy); |
| 424 | if (hSocket == INVALID_SOCKET) { |
| 425 | return nullptr; |
| 426 | } |
| 427 | connected = ConnectThroughProxy(proxy, addrConnect.ToStringIP(), addrConnect.GetPort(), hSocket, nConnectTimeout, &proxyConnectionFailed); |
nothing calls this directly
no test coverage detected