@@ -535,24 +535,10 @@ static void LogConnectFailure(bool manual_connection, const char* fmt, const Arg
535
535
}
536
536
}
537
537
538
- std::unique_ptr<Sock> ConnectDirectly (const CService& dest , bool manual_connection)
538
+ static bool ConnectToSocket (const Sock& sock, struct sockaddr * sockaddr, socklen_t len, const std::string& dest_str , bool manual_connection)
539
539
{
540
- auto sock = CreateSock (dest.GetSAFamily ());
541
- if (!sock) {
542
- LogPrintLevel (BCLog::NET, BCLog::Level::Error, " Cannot create a socket for connecting to %s\n " , dest.ToStringAddrPort ());
543
- return {};
544
- }
545
-
546
- // Create a sockaddr from the specified service.
547
- struct sockaddr_storage sockaddr;
548
- socklen_t len = sizeof (sockaddr);
549
- if (!dest.GetSockAddr ((struct sockaddr *)&sockaddr, &len)) {
550
- LogPrintf (" Cannot connect to %s: unsupported network\n " , dest.ToStringAddrPort ());
551
- return {};
552
- }
553
-
554
- // Connect to the dest service on the hSocket socket.
555
- if (sock->Connect (reinterpret_cast <struct sockaddr *>(&sockaddr), len) == SOCKET_ERROR) {
540
+ // Connect to `sockaddr` using `sock`.
541
+ if (sock.Connect (sockaddr, len) == SOCKET_ERROR) {
556
542
int nErr = WSAGetLastError ();
557
543
// WSAEINVAL is here because some legacy version of winsock uses it
558
544
if (nErr == WSAEINPROGRESS || nErr == WSAEWOULDBLOCK || nErr == WSAEINVAL)
@@ -562,14 +548,14 @@ std::unique_ptr<Sock> ConnectDirectly(const CService& dest, bool manual_connecti
562
548
// synchronously to check for successful connection with a timeout.
563
549
const Sock::Event requested = Sock::RECV | Sock::SEND;
564
550
Sock::Event occurred;
565
- if (!sock-> Wait (std::chrono::milliseconds{nConnectTimeout}, requested, &occurred)) {
551
+ if (!sock. Wait (std::chrono::milliseconds{nConnectTimeout}, requested, &occurred)) {
566
552
LogPrintf (" wait for connect to %s failed: %s\n " ,
567
- dest. ToStringAddrPort () ,
553
+ dest_str ,
568
554
NetworkErrorString (WSAGetLastError ()));
569
- return {} ;
555
+ return false ;
570
556
} else if (occurred == 0 ) {
571
- LogPrint (BCLog::NET, " connection attempt to %s timed out\n " , dest. ToStringAddrPort () );
572
- return {} ;
557
+ LogPrint (BCLog::NET, " connection attempt to %s timed out\n " , dest_str );
558
+ return false ;
573
559
}
574
560
575
561
// Even if the wait was successful, the connect might not
@@ -578,17 +564,17 @@ std::unique_ptr<Sock> ConnectDirectly(const CService& dest, bool manual_connecti
578
564
// sockerr here.
579
565
int sockerr;
580
566
socklen_t sockerr_len = sizeof (sockerr);
581
- if (sock-> GetSockOpt (SOL_SOCKET, SO_ERROR, (sockopt_arg_type)&sockerr, &sockerr_len) ==
567
+ if (sock. GetSockOpt (SOL_SOCKET, SO_ERROR, (sockopt_arg_type)&sockerr, &sockerr_len) ==
582
568
SOCKET_ERROR) {
583
- LogPrintf (" getsockopt() for %s failed: %s\n " , dest. ToStringAddrPort () , NetworkErrorString (WSAGetLastError ()));
584
- return {} ;
569
+ LogPrintf (" getsockopt() for %s failed: %s\n " , dest_str , NetworkErrorString (WSAGetLastError ()));
570
+ return false ;
585
571
}
586
572
if (sockerr != 0 ) {
587
573
LogConnectFailure (manual_connection,
588
574
" connect() to %s failed after wait: %s" ,
589
- dest. ToStringAddrPort () ,
575
+ dest_str ,
590
576
NetworkErrorString (sockerr));
591
- return {} ;
577
+ return false ;
592
578
}
593
579
}
594
580
#ifdef WIN32
@@ -597,11 +583,71 @@ std::unique_ptr<Sock> ConnectDirectly(const CService& dest, bool manual_connecti
597
583
else
598
584
#endif
599
585
{
600
- LogConnectFailure (manual_connection, " connect() to %s failed: %s" , dest. ToStringAddrPort () , NetworkErrorString (WSAGetLastError ()));
601
- return {} ;
586
+ LogConnectFailure (manual_connection, " connect() to %s failed: %s" , dest_str , NetworkErrorString (WSAGetLastError ()));
587
+ return false ;
602
588
}
603
589
}
590
+ return true ;
591
+ }
592
+
593
+ std::unique_ptr<Sock> ConnectDirectly (const CService& dest, bool manual_connection)
594
+ {
595
+ auto sock = CreateSock (dest.GetSAFamily ());
596
+ if (!sock) {
597
+ LogPrintLevel (BCLog::NET, BCLog::Level::Error, " Cannot create a socket for connecting to %s\n " , dest.ToStringAddrPort ());
598
+ return {};
599
+ }
600
+
601
+ // Create a sockaddr from the specified service.
602
+ struct sockaddr_storage sockaddr;
603
+ socklen_t len = sizeof (sockaddr);
604
+ if (!dest.GetSockAddr ((struct sockaddr *)&sockaddr, &len)) {
605
+ LogPrintf (" Cannot get sockaddr for %s: unsupported network\n " , dest.ToStringAddrPort ());
606
+ return {};
607
+ }
608
+
609
+ if (!ConnectToSocket (*sock, (struct sockaddr *)&sockaddr, len, dest.ToStringAddrPort (), manual_connection)) {
610
+ LogPrintf (" Cannot connect to socket for %s\n " , dest.ToStringAddrPort ());
611
+ return {};
612
+ }
613
+
614
+ return sock;
615
+ }
616
+
617
+ std::unique_ptr<Sock> Proxy::Connect () const
618
+ {
619
+ if (!IsValid ()) {
620
+ LogPrintf (" Cannot connect to invalid Proxy\n " );
621
+ return {};
622
+ }
623
+
624
+ if (!m_is_unix_socket) return ConnectDirectly (proxy, /* manual_connection=*/ true );
625
+
626
+ #if HAVE_SOCKADDR_UN
627
+ auto sock = CreateSock (AF_UNIX);
628
+ if (!sock) {
629
+ LogPrintLevel (BCLog::NET, BCLog::Level::Error, " Cannot create a socket for connecting to %s\n " , m_unix_socket_path);
630
+ return {};
631
+ }
632
+
633
+ const std::string path{m_unix_socket_path.substr (ADDR_PREFIX_UNIX.length ())};
634
+
635
+ struct sockaddr_un addrun;
636
+ memset (&addrun, 0 , sizeof (addrun));
637
+ addrun.sun_family = AF_UNIX;
638
+ // leave the last char in addrun.sun_path[] to be always '\0'
639
+ memcpy (addrun.sun_path , path.c_str (), std::min (sizeof (addrun.sun_path ) - 1 , path.length ()));
640
+ socklen_t len = sizeof (addrun);
641
+
642
+ if (!ConnectToSocket (*sock, (struct sockaddr *)&addrun, len, path, /* manual_connection=*/ true )) {
643
+ LogPrintf (" Cannot connect to socket for %s\n " , path);
644
+ return {};
645
+ }
646
+
604
647
return sock;
648
+ #else
649
+ return {};
650
+ #endif
605
651
}
606
652
607
653
bool SetProxy (enum Network net, const Proxy &addrProxy) {
@@ -658,7 +704,7 @@ std::unique_ptr<Sock> ConnectThroughProxy(const Proxy& proxy,
658
704
bool & proxy_connection_failed)
659
705
{
660
706
// first connect to proxy server
661
- auto sock = ConnectDirectly ( proxy.proxy , /* manual_connection= */ true );
707
+ auto sock = proxy.Connect ( );
662
708
if (!sock) {
663
709
proxy_connection_failed = true ;
664
710
return {};
0 commit comments