| 376 | } |
| 377 | |
| 378 | CNode* CConnman::ConnectNode(CAddress addrConnect, |
| 379 | const char* pszDest, |
| 380 | bool fCountFailure, |
| 381 | ConnectionType conn_type, |
| 382 | bool use_v2transport, |
| 383 | const std::optional<Proxy>& proxy_override) |
| 384 | { |
| 385 | AssertLockNotHeld(m_nodes_mutex); |
| 386 | AssertLockNotHeld(m_unused_i2p_sessions_mutex); |
| 387 | assert(conn_type != ConnectionType::INBOUND); |
| 388 | |
| 389 | if (pszDest == nullptr) { |
| 390 | if (IsLocal(addrConnect)) |
| 391 | return nullptr; |
| 392 | |
| 393 | // Look for an existing connection |
| 394 | if (AlreadyConnectedToAddressPort(addrConnect)) { |
| 395 | LogInfo("Failed to open new connection to %s, already connected", addrConnect.ToStringAddrPort()); |
| 396 | return nullptr; |
| 397 | } |
| 398 | } |
| 399 | |
| 400 | LogDebug(BCLog::NET, "trying %s connection (%s) to %s, lastseen=%.1fhrs\n", |
| 401 | use_v2transport ? "v2" : "v1", |
| 402 | ConnectionTypeAsString(conn_type), |
| 403 | pszDest ? pszDest : addrConnect.ToStringAddrPort(), |
| 404 | Ticks<HoursDouble>(pszDest ? 0h : Now<NodeSeconds>() - addrConnect.nTime)); |
| 405 | |
| 406 | // Resolve |
| 407 | const uint16_t default_port{pszDest != nullptr ? GetDefaultPort(pszDest) : |
| 408 | m_params.GetDefaultPort()}; |
| 409 | |
| 410 | // Collection of addresses to try to connect to: either all dns resolved addresses if a domain name (pszDest) is provided, or addrConnect otherwise. |
| 411 | std::vector<CAddress> connect_to{}; |
| 412 | if (pszDest) { |
| 413 | std::vector<CService> resolved{Lookup(pszDest, default_port, fNameLookup && !HaveNameProxy(), 256)}; |
| 414 | if (!resolved.empty()) { |
| 415 | std::shuffle(resolved.begin(), resolved.end(), FastRandomContext()); |
| 416 | // If the connection is made by name, it can be the case that the name resolves to more than one address. |
| 417 | // We don't want to connect any more of them if we are already connected to one |
| 418 | for (const auto& r : resolved) { |
| 419 | addrConnect = CAddress{MaybeFlipIPv6toCJDNS(r), NODE_NONE}; |
| 420 | if (!addrConnect.IsValid()) { |
| 421 | LogDebug(BCLog::NET, "Resolver returned invalid address %s for %s\n", addrConnect.ToStringAddrPort(), pszDest); |
| 422 | return nullptr; |
| 423 | } |
| 424 | // It is possible that we already have a connection to the IP/port pszDest resolved to. |
| 425 | // In that case, drop the connection that was just created. |
| 426 | if (AlreadyConnectedToAddressPort(addrConnect)) { |
| 427 | LogInfo("Not opening a connection to %s, already connected to %s\n", pszDest, addrConnect.ToStringAddrPort()); |
| 428 | return nullptr; |
| 429 | } |
| 430 | // Add the address to the resolved addresses vector so we can try to connect to it later on |
| 431 | connect_to.push_back(addrConnect); |
| 432 | } |
| 433 | } else { |
| 434 | // For resolution via proxy |
| 435 | connect_to.push_back(addrConnect); |
nothing calls this directly
no test coverage detected