@@ -331,8 +331,7 @@ enum class IntrRecvError {
331331 * @param data The buffer where the read bytes should be stored.
332332 * @param len The number of bytes to read into the specified buffer.
333333 * @param timeout The total timeout in milliseconds for this read.
334- * @param hSocket The socket (has to be in non-blocking mode) from which to read
335- * bytes.
334+ * @param sock The socket (has to be in non-blocking mode) from which to read bytes.
336335 *
337336 * @returns An IntrRecvError indicating the resulting status of this read.
338337 * IntrRecvError::OK only if all of the specified number of bytes were
@@ -342,15 +341,15 @@ enum class IntrRecvError {
342341 * Sockets can be made non-blocking with SetSocketNonBlocking(const
343342 * SOCKET&, bool).
344343 */
345- static IntrRecvError InterruptibleRecv (uint8_t * data, size_t len, int timeout, const SOCKET& hSocket )
344+ static IntrRecvError InterruptibleRecv (uint8_t * data, size_t len, int timeout, const Sock& sock )
346345{
347346 int64_t curTime = GetTimeMillis ();
348347 int64_t endTime = curTime + timeout;
349348 // Maximum time to wait for I/O readiness. It will take up until this time
350349 // (in millis) to break off in case of an interruption.
351350 const int64_t maxWait = 1000 ;
352351 while (len > 0 && curTime < endTime) {
353- ssize_t ret = recv (hSocket, ( char *) data, len, 0 ); // Optimistically try the recv first
352+ ssize_t ret = sock. Recv ( data, len, 0 ); // Optimistically try the recv first
354353 if (ret > 0 ) {
355354 len -= ret;
356355 data += ret;
@@ -359,25 +358,10 @@ static IntrRecvError InterruptibleRecv(uint8_t* data, size_t len, int timeout, c
359358 } else { // Other error or blocking
360359 int nErr = WSAGetLastError ();
361360 if (nErr == WSAEINPROGRESS || nErr == WSAEWOULDBLOCK || nErr == WSAEINVAL) {
362- if (!IsSelectableSocket (hSocket)) {
363- return IntrRecvError::NetworkError;
364- }
365361 // Only wait at most maxWait milliseconds at a time, unless
366362 // we're approaching the end of the specified total timeout
367363 int timeout_ms = std::min (endTime - curTime, maxWait);
368- #ifdef USE_POLL
369- struct pollfd pollfd = {};
370- pollfd.fd = hSocket;
371- pollfd.events = POLLIN;
372- int nRet = poll (&pollfd, 1 , timeout_ms);
373- #else
374- struct timeval tval = MillisToTimeval (timeout_ms);
375- fd_set fdset;
376- FD_ZERO (&fdset);
377- FD_SET (hSocket, &fdset);
378- int nRet = select (hSocket + 1 , &fdset, nullptr , nullptr , &tval);
379- #endif
380- if (nRet == SOCKET_ERROR) {
364+ if (!sock.Wait (std::chrono::milliseconds{timeout_ms}, Sock::RECV)) {
381365 return IntrRecvError::NetworkError;
382366 }
383367 } else {
@@ -431,7 +415,7 @@ static std::string Socks5ErrorString(uint8_t err)
431415 * @param port The destination port.
432416 * @param auth The credentials with which to authenticate with the specified
433417 * SOCKS5 proxy.
434- * @param hSocket The SOCKS5 proxy socket.
418+ * @param sock The SOCKS5 proxy socket.
435419 *
436420 * @returns Whether or not the operation succeeded.
437421 *
@@ -441,7 +425,10 @@ static std::string Socks5ErrorString(uint8_t err)
441425 * @see <a href="https://www.ietf.org/rfc/rfc1928.txt">RFC1928: SOCKS Protocol
442426 * Version 5</a>
443427 */
444- static bool Socks5 (const std::string& strDest, int port, const ProxyCredentials *auth, const SOCKET& hSocket)
428+ static bool Socks5 (const std::string& strDest,
429+ int port,
430+ const ProxyCredentials* auth,
431+ const Sock& sock)
445432{
446433 IntrRecvError recvr;
447434 LogPrint (BCLog::NET, " SOCKS5 connecting %s\n " , strDest);
@@ -459,12 +446,12 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials
459446 vSocks5Init.push_back (0x01 ); // 1 method identifier follows...
460447 vSocks5Init.push_back (SOCKS5Method::NOAUTH);
461448 }
462- ssize_t ret = send (hSocket, ( const char *) vSocks5Init.data (), vSocks5Init.size (), MSG_NOSIGNAL);
449+ ssize_t ret = sock. Send ( vSocks5Init.data (), vSocks5Init.size (), MSG_NOSIGNAL);
463450 if (ret != (ssize_t )vSocks5Init.size ()) {
464451 return error (" Error sending to proxy" );
465452 }
466453 uint8_t pchRet1[2 ];
467- if ((recvr = InterruptibleRecv (pchRet1, 2 , SOCKS5_RECV_TIMEOUT, hSocket )) != IntrRecvError::OK) {
454+ if ((recvr = InterruptibleRecv (pchRet1, 2 , SOCKS5_RECV_TIMEOUT, sock )) != IntrRecvError::OK) {
468455 LogPrintf (" Socks5() connect to %s:%d failed: InterruptibleRecv() timeout or other failure\n " , strDest, port);
469456 return false ;
470457 }
@@ -481,13 +468,13 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials
481468 vAuth.insert (vAuth.end (), auth->username .begin (), auth->username .end ());
482469 vAuth.push_back (auth->password .size ());
483470 vAuth.insert (vAuth.end (), auth->password .begin (), auth->password .end ());
484- ret = send (hSocket, ( const char *) vAuth.data (), vAuth.size (), MSG_NOSIGNAL);
471+ ret = sock. Send ( vAuth.data (), vAuth.size (), MSG_NOSIGNAL);
485472 if (ret != (ssize_t )vAuth.size ()) {
486473 return error (" Error sending authentication to proxy" );
487474 }
488475 LogPrint (BCLog::PROXY, " SOCKS5 sending proxy authentication %s:%s\n " , auth->username , auth->password );
489476 uint8_t pchRetA[2 ];
490- if ((recvr = InterruptibleRecv (pchRetA, 2 , SOCKS5_RECV_TIMEOUT, hSocket )) != IntrRecvError::OK) {
477+ if ((recvr = InterruptibleRecv (pchRetA, 2 , SOCKS5_RECV_TIMEOUT, sock )) != IntrRecvError::OK) {
491478 return error (" Error reading proxy authentication response" );
492479 }
493480 if (pchRetA[0 ] != 0x01 || pchRetA[1 ] != 0x00 ) {
@@ -507,12 +494,12 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials
507494 vSocks5.insert (vSocks5.end (), strDest.begin (), strDest.end ());
508495 vSocks5.push_back ((port >> 8 ) & 0xFF );
509496 vSocks5.push_back ((port >> 0 ) & 0xFF );
510- ret = send (hSocket, ( const char *) vSocks5.data (), vSocks5.size (), MSG_NOSIGNAL);
497+ ret = sock. Send ( vSocks5.data (), vSocks5.size (), MSG_NOSIGNAL);
511498 if (ret != (ssize_t )vSocks5.size ()) {
512499 return error (" Error sending to proxy" );
513500 }
514501 uint8_t pchRet2[4 ];
515- if ((recvr = InterruptibleRecv (pchRet2, 4 , SOCKS5_RECV_TIMEOUT, hSocket )) != IntrRecvError::OK) {
502+ if ((recvr = InterruptibleRecv (pchRet2, 4 , SOCKS5_RECV_TIMEOUT, sock )) != IntrRecvError::OK) {
516503 if (recvr == IntrRecvError::Timeout) {
517504 /* If a timeout happens here, this effectively means we timed out while connecting
518505 * to the remote node. This is very common for Tor, so do not print an
@@ -536,24 +523,24 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials
536523 uint8_t pchRet3[256 ];
537524 switch (pchRet2[3 ])
538525 {
539- case SOCKS5Atyp::IPV4: recvr = InterruptibleRecv (pchRet3, 4 , SOCKS5_RECV_TIMEOUT, hSocket ); break ;
540- case SOCKS5Atyp::IPV6: recvr = InterruptibleRecv (pchRet3, 16 , SOCKS5_RECV_TIMEOUT, hSocket ); break ;
526+ case SOCKS5Atyp::IPV4: recvr = InterruptibleRecv (pchRet3, 4 , SOCKS5_RECV_TIMEOUT, sock ); break ;
527+ case SOCKS5Atyp::IPV6: recvr = InterruptibleRecv (pchRet3, 16 , SOCKS5_RECV_TIMEOUT, sock ); break ;
541528 case SOCKS5Atyp::DOMAINNAME:
542529 {
543- recvr = InterruptibleRecv (pchRet3, 1 , SOCKS5_RECV_TIMEOUT, hSocket );
530+ recvr = InterruptibleRecv (pchRet3, 1 , SOCKS5_RECV_TIMEOUT, sock );
544531 if (recvr != IntrRecvError::OK) {
545532 return error (" Error reading from proxy" );
546533 }
547534 int nRecv = pchRet3[0 ];
548- recvr = InterruptibleRecv (pchRet3, nRecv, SOCKS5_RECV_TIMEOUT, hSocket );
535+ recvr = InterruptibleRecv (pchRet3, nRecv, SOCKS5_RECV_TIMEOUT, sock );
549536 break ;
550537 }
551538 default : return error (" Error: malformed proxy response" );
552539 }
553540 if (recvr != IntrRecvError::OK) {
554541 return error (" Error reading from proxy" );
555542 }
556- if ((recvr = InterruptibleRecv (pchRet3, 2 , SOCKS5_RECV_TIMEOUT, hSocket )) != IntrRecvError::OK) {
543+ if ((recvr = InterruptibleRecv (pchRet3, 2 , SOCKS5_RECV_TIMEOUT, sock )) != IntrRecvError::OK) {
557544 return error (" Error reading from proxy" );
558545 }
559546 LogPrint (BCLog::NET, " SOCKS5 connected %s\n " , strDest);
@@ -778,18 +765,23 @@ bool IsProxy(const CNetAddr &addr) {
778765 * @param proxy The SOCKS5 proxy.
779766 * @param strDest The destination service to which to connect.
780767 * @param port The destination port.
781- * @param hSocket The socket on which to connect to the SOCKS5 proxy.
768+ * @param sock The socket on which to connect to the SOCKS5 proxy.
782769 * @param nTimeout Wait this many milliseconds for the connection to the SOCKS5
783770 * proxy to be established.
784771 * @param[out] outProxyConnectionFailed Whether or not the connection to the
785772 * SOCKS5 proxy failed.
786773 *
787774 * @returns Whether or not the operation succeeded.
788775 */
789- bool ConnectThroughProxy (const proxyType &proxy, const std::string& strDest, int port, const SOCKET& hSocket, int nTimeout, bool & outProxyConnectionFailed)
776+ bool ConnectThroughProxy (const proxyType& proxy,
777+ const std::string& strDest,
778+ int port,
779+ const Sock& sock,
780+ int nTimeout,
781+ bool & outProxyConnectionFailed)
790782{
791783 // first connect to proxy server
792- if (!ConnectSocketDirectly (proxy.proxy , hSocket , nTimeout, true )) {
784+ if (!ConnectSocketDirectly (proxy.proxy , sock. Get () , nTimeout, true )) {
793785 outProxyConnectionFailed = true ;
794786 return false ;
795787 }
@@ -798,11 +790,11 @@ bool ConnectThroughProxy(const proxyType &proxy, const std::string& strDest, int
798790 ProxyCredentials random_auth;
799791 static std::atomic_int counter (0 );
800792 random_auth.username = random_auth.password = strprintf (" %i" , counter++);
801- if (!Socks5 (strDest, (uint16_t )port, &random_auth, hSocket )) {
793+ if (!Socks5 (strDest, (uint16_t )port, &random_auth, sock )) {
802794 return false ;
803795 }
804796 } else {
805- if (!Socks5 (strDest, (uint16_t )port, 0 , hSocket )) {
797+ if (!Socks5 (strDest, (uint16_t )port, 0 , sock )) {
806798 return false ;
807799 }
808800 }
0 commit comments