MCPcopy Create free account
hub / github.com/ElementsProject/elements / ConnectSocketDirectly

Function ConnectSocketDirectly

src/netbase.cpp:541–606  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

539}
540
541bool ConnectSocketDirectly(const CService &addrConnect, const Sock& sock, int nTimeout, bool manual_connection)
542{
543 // Create a sockaddr from the specified service.
544 struct sockaddr_storage sockaddr;
545 socklen_t len = sizeof(sockaddr);
546 if (sock.Get() == INVALID_SOCKET) {
547 LogPrintf("Cannot connect to %s: invalid socket\n", addrConnect.ToString());
548 return false;
549 }
550 if (!addrConnect.GetSockAddr((struct sockaddr*)&sockaddr, &len)) {
551 LogPrintf("Cannot connect to %s: unsupported network\n", addrConnect.ToString());
552 return false;
553 }
554
555 // Connect to the addrConnect service on the hSocket socket.
556 if (sock.Connect(reinterpret_cast<struct sockaddr*>(&sockaddr), len) == SOCKET_ERROR) {
557 int nErr = WSAGetLastError();
558 // WSAEINVAL is here because some legacy version of winsock uses it
559 if (nErr == WSAEINPROGRESS || nErr == WSAEWOULDBLOCK || nErr == WSAEINVAL)
560 {
561 // Connection didn't actually fail, but is being established
562 // asynchronously. Thus, use async I/O api (select/poll)
563 // synchronously to check for successful connection with a timeout.
564 const Sock::Event requested = Sock::RECV | Sock::SEND;
565 Sock::Event occurred;
566 if (!sock.Wait(std::chrono::milliseconds{nTimeout}, requested, &occurred)) {
567 LogPrintf("wait for connect to %s failed: %s\n",
568 addrConnect.ToString(),
569 NetworkErrorString(WSAGetLastError()));
570 return false;
571 } else if (occurred == 0) {
572 LogPrint(BCLog::NET, "connection attempt to %s timed out\n", addrConnect.ToString());
573 return false;
574 }
575
576 // Even if the wait was successful, the connect might not
577 // have been successful. The reason for this failure is hidden away
578 // in the SO_ERROR for the socket in modern systems. We read it into
579 // sockerr here.
580 int sockerr;
581 socklen_t sockerr_len = sizeof(sockerr);
582 if (sock.GetSockOpt(SOL_SOCKET, SO_ERROR, (sockopt_arg_type)&sockerr, &sockerr_len) ==
583 SOCKET_ERROR) {
584 LogPrintf("getsockopt() for %s failed: %s\n", addrConnect.ToString(), NetworkErrorString(WSAGetLastError()));
585 return false;
586 }
587 if (sockerr != 0) {
588 LogConnectFailure(manual_connection,
589 "connect() to %s failed after wait: %s",
590 addrConnect.ToString(),
591 NetworkErrorString(sockerr));
592 return false;
593 }
594 }
595#ifdef WIN32
596 else if (WSAGetLastError() != WSAEISCONN)
597#else
598 else

Callers 3

HelloMethod · 0.85
ConnectThroughProxyFunction · 0.85
ConnectNodeMethod · 0.85

Calls 8

NetworkErrorStringFunction · 0.85
LogConnectFailureFunction · 0.85
GetSockAddrMethod · 0.80
GetMethod · 0.45
ToStringMethod · 0.45
ConnectMethod · 0.45
WaitMethod · 0.45
GetSockOptMethod · 0.45

Tested by

no test coverage detected