@@ -313,12 +313,11 @@ std::string Socks5ErrorString(uint8_t err)
313
313
}
314
314
315
315
/* * Connect using SOCKS5 (as described in RFC1928) */
316
- static bool Socks5 (const std::string& strDest, int port, const ProxyCredentials *auth, SOCKET& hSocket)
316
+ static bool Socks5 (const std::string& strDest, int port, const ProxyCredentials *auth, const SOCKET& hSocket)
317
317
{
318
318
IntrRecvError recvr;
319
319
LogPrint (BCLog::NET, " SOCKS5 connecting %s\n " , strDest);
320
320
if (strDest.size () > 255 ) {
321
- CloseSocket (hSocket);
322
321
return error (" Hostname too long" );
323
322
}
324
323
// Accepted authentication methods
@@ -334,17 +333,14 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials
334
333
}
335
334
ssize_t ret = send (hSocket, (const char *)vSocks5Init.data (), vSocks5Init.size (), MSG_NOSIGNAL);
336
335
if (ret != (ssize_t )vSocks5Init.size ()) {
337
- CloseSocket (hSocket);
338
336
return error (" Error sending to proxy" );
339
337
}
340
338
uint8_t pchRet1[2 ];
341
339
if ((recvr = InterruptibleRecv (pchRet1, 2 , SOCKS5_RECV_TIMEOUT, hSocket)) != IntrRecvError::OK) {
342
- CloseSocket (hSocket);
343
340
LogPrintf (" Socks5() connect to %s:%d failed: InterruptibleRecv() timeout or other failure\n " , strDest, port);
344
341
return false ;
345
342
}
346
343
if (pchRet1[0 ] != SOCKSVersion::SOCKS5) {
347
- CloseSocket (hSocket);
348
344
return error (" Proxy failed to initialize" );
349
345
}
350
346
if (pchRet1[1 ] == SOCKS5Method::USER_PASS && auth) {
@@ -359,23 +355,19 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials
359
355
vAuth.insert (vAuth.end (), auth->password .begin (), auth->password .end ());
360
356
ret = send (hSocket, (const char *)vAuth.data (), vAuth.size (), MSG_NOSIGNAL);
361
357
if (ret != (ssize_t )vAuth.size ()) {
362
- CloseSocket (hSocket);
363
358
return error (" Error sending authentication to proxy" );
364
359
}
365
360
LogPrint (BCLog::PROXY, " SOCKS5 sending proxy authentication %s:%s\n " , auth->username , auth->password );
366
361
uint8_t pchRetA[2 ];
367
362
if ((recvr = InterruptibleRecv (pchRetA, 2 , SOCKS5_RECV_TIMEOUT, hSocket)) != IntrRecvError::OK) {
368
- CloseSocket (hSocket);
369
363
return error (" Error reading proxy authentication response" );
370
364
}
371
365
if (pchRetA[0 ] != 0x01 || pchRetA[1 ] != 0x00 ) {
372
- CloseSocket (hSocket);
373
366
return error (" Proxy authentication unsuccessful" );
374
367
}
375
368
} else if (pchRet1[1 ] == SOCKS5Method::NOAUTH) {
376
369
// Perform no authentication
377
370
} else {
378
- CloseSocket (hSocket);
379
371
return error (" Proxy requested wrong authentication method %02x" , pchRet1[1 ]);
380
372
}
381
373
std::vector<uint8_t > vSocks5;
@@ -389,12 +381,10 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials
389
381
vSocks5.push_back ((port >> 0 ) & 0xFF );
390
382
ret = send (hSocket, (const char *)vSocks5.data (), vSocks5.size (), MSG_NOSIGNAL);
391
383
if (ret != (ssize_t )vSocks5.size ()) {
392
- CloseSocket (hSocket);
393
384
return error (" Error sending to proxy" );
394
385
}
395
386
uint8_t pchRet2[4 ];
396
387
if ((recvr = InterruptibleRecv (pchRet2, 4 , SOCKS5_RECV_TIMEOUT, hSocket)) != IntrRecvError::OK) {
397
- CloseSocket (hSocket);
398
388
if (recvr == IntrRecvError::Timeout) {
399
389
/* If a timeout happens here, this effectively means we timed out while connecting
400
390
* to the remote node. This is very common for Tor, so do not print an
@@ -405,17 +395,14 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials
405
395
}
406
396
}
407
397
if (pchRet2[0 ] != SOCKSVersion::SOCKS5) {
408
- CloseSocket (hSocket);
409
398
return error (" Proxy failed to accept request" );
410
399
}
411
400
if (pchRet2[1 ] != SOCKS5Reply::SUCCEEDED) {
412
401
// Failures to connect to a peer that are not proxy errors
413
- CloseSocket (hSocket);
414
402
LogPrintf (" Socks5() connect to %s:%d failed: %s\n " , strDest, port, Socks5ErrorString (pchRet2[1 ]));
415
403
return false ;
416
404
}
417
405
if (pchRet2[2 ] != 0x00 ) { // Reserved field must be 0
418
- CloseSocket (hSocket);
419
406
return error (" Error: malformed proxy response" );
420
407
}
421
408
uint8_t pchRet3[256 ];
@@ -427,41 +414,42 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials
427
414
{
428
415
recvr = InterruptibleRecv (pchRet3, 1 , SOCKS5_RECV_TIMEOUT, hSocket);
429
416
if (recvr != IntrRecvError::OK) {
430
- CloseSocket (hSocket);
431
417
return error (" Error reading from proxy" );
432
418
}
433
419
int nRecv = pchRet3[0 ];
434
420
recvr = InterruptibleRecv (pchRet3, nRecv, SOCKS5_RECV_TIMEOUT, hSocket);
435
421
break ;
436
422
}
437
- default : CloseSocket (hSocket); return error (" Error: malformed proxy response" );
423
+ default : return error (" Error: malformed proxy response" );
438
424
}
439
425
if (recvr != IntrRecvError::OK) {
440
- CloseSocket (hSocket);
441
426
return error (" Error reading from proxy" );
442
427
}
443
428
if ((recvr = InterruptibleRecv (pchRet3, 2 , SOCKS5_RECV_TIMEOUT, hSocket)) != IntrRecvError::OK) {
444
- CloseSocket (hSocket);
445
429
return error (" Error reading from proxy" );
446
430
}
447
431
LogPrint (BCLog::NET, " SOCKS5 connected %s\n " , strDest);
448
432
return true ;
449
433
}
450
434
451
- bool ConnectSocketDirectly (const CService &addrConnect, SOCKET& hSocketRet, int nTimeout )
435
+ SOCKET CreateSocket (const CService &addrConnect)
452
436
{
453
- hSocketRet = INVALID_SOCKET;
454
-
455
437
struct sockaddr_storage sockaddr;
456
438
socklen_t len = sizeof (sockaddr);
457
439
if (!addrConnect.GetSockAddr ((struct sockaddr *)&sockaddr, &len)) {
458
- LogPrintf (" Cannot connect to %s: unsupported network\n " , addrConnect.ToString ());
459
- return false ;
440
+ LogPrintf (" Cannot create socket for %s: unsupported network\n " , addrConnect.ToString ());
441
+ return INVALID_SOCKET ;
460
442
}
461
443
462
444
SOCKET hSocket = socket (((struct sockaddr *)&sockaddr)->sa_family , SOCK_STREAM, IPPROTO_TCP);
463
445
if (hSocket == INVALID_SOCKET)
464
- return false ;
446
+ return INVALID_SOCKET;
447
+
448
+ if (!IsSelectableSocket (hSocket)) {
449
+ CloseSocket (hSocket);
450
+ LogPrintf (" Cannot create connection: non-selectable socket created (fd >= FD_SETSIZE ?)\n " );
451
+ return INVALID_SOCKET;
452
+ }
465
453
466
454
#ifdef SO_NOSIGPIPE
467
455
int set = 1 ;
@@ -475,9 +463,23 @@ bool ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRet, int
475
463
// Set to non-blocking
476
464
if (!SetSocketNonBlocking (hSocket, true )) {
477
465
CloseSocket (hSocket);
478
- return error (" ConnectSocketDirectly: Setting socket to non-blocking failed, error %s\n " , NetworkErrorString (WSAGetLastError ()));
466
+ LogPrintf (" ConnectSocketDirectly: Setting socket to non-blocking failed, error %s\n " , NetworkErrorString (WSAGetLastError ()));
479
467
}
468
+ return hSocket;
469
+ }
480
470
471
+ bool ConnectSocketDirectly (const CService &addrConnect, const SOCKET& hSocket, int nTimeout)
472
+ {
473
+ struct sockaddr_storage sockaddr;
474
+ socklen_t len = sizeof (sockaddr);
475
+ if (hSocket == INVALID_SOCKET) {
476
+ LogPrintf (" Cannot connect to %s: invalid socket\n " , addrConnect.ToString ());
477
+ return false ;
478
+ }
479
+ if (!addrConnect.GetSockAddr ((struct sockaddr *)&sockaddr, &len)) {
480
+ LogPrintf (" Cannot connect to %s: unsupported network\n " , addrConnect.ToString ());
481
+ return false ;
482
+ }
481
483
if (connect (hSocket, (struct sockaddr *)&sockaddr, len) == SOCKET_ERROR)
482
484
{
483
485
int nErr = WSAGetLastError ();
@@ -492,13 +494,11 @@ bool ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRet, int
492
494
if (nRet == 0 )
493
495
{
494
496
LogPrint (BCLog::NET, " connection to %s timeout\n " , addrConnect.ToString ());
495
- CloseSocket (hSocket);
496
497
return false ;
497
498
}
498
499
if (nRet == SOCKET_ERROR)
499
500
{
500
501
LogPrintf (" select() for %s failed: %s\n " , addrConnect.ToString (), NetworkErrorString (WSAGetLastError ()));
501
- CloseSocket (hSocket);
502
502
return false ;
503
503
}
504
504
socklen_t nRetSize = sizeof (nRet);
@@ -509,13 +509,11 @@ bool ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRet, int
509
509
#endif
510
510
{
511
511
LogPrintf (" getsockopt() for %s failed: %s\n " , addrConnect.ToString (), NetworkErrorString (WSAGetLastError ()));
512
- CloseSocket (hSocket);
513
512
return false ;
514
513
}
515
514
if (nRet != 0 )
516
515
{
517
516
LogPrintf (" connect() to %s failed after select(): %s\n " , addrConnect.ToString (), NetworkErrorString (nRet));
518
- CloseSocket (hSocket);
519
517
return false ;
520
518
}
521
519
}
@@ -526,12 +524,9 @@ bool ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRet, int
526
524
#endif
527
525
{
528
526
LogPrintf (" connect() to %s failed: %s\n " , addrConnect.ToString (), NetworkErrorString (WSAGetLastError ()));
529
- CloseSocket (hSocket);
530
527
return false ;
531
528
}
532
529
}
533
-
534
- hSocketRet = hSocket;
535
530
return true ;
536
531
}
537
532
@@ -583,9 +578,8 @@ bool IsProxy(const CNetAddr &addr) {
583
578
return false ;
584
579
}
585
580
586
- bool ConnectThroughProxy (const proxyType &proxy, const std::string& strDest, int port, SOCKET& hSocketRet , int nTimeout, bool *outProxyConnectionFailed)
581
+ bool ConnectThroughProxy (const proxyType &proxy, const std::string& strDest, int port, const SOCKET& hSocket , int nTimeout, bool *outProxyConnectionFailed)
587
582
{
588
- SOCKET hSocket = INVALID_SOCKET;
589
583
// first connect to proxy server
590
584
if (!ConnectSocketDirectly (proxy.proxy , hSocket, nTimeout)) {
591
585
if (outProxyConnectionFailed)
@@ -597,14 +591,14 @@ bool ConnectThroughProxy(const proxyType &proxy, const std::string& strDest, int
597
591
ProxyCredentials random_auth;
598
592
static std::atomic_int counter (0 );
599
593
random_auth.username = random_auth.password = strprintf (" %i" , counter++);
600
- if (!Socks5 (strDest, (unsigned short )port, &random_auth, hSocket))
594
+ if (!Socks5 (strDest, (unsigned short )port, &random_auth, hSocket)) {
601
595
return false ;
596
+ }
602
597
} else {
603
- if (!Socks5 (strDest, (unsigned short )port, 0 , hSocket))
598
+ if (!Socks5 (strDest, (unsigned short )port, 0 , hSocket)) {
604
599
return false ;
600
+ }
605
601
}
606
-
607
- hSocketRet = hSocket;
608
602
return true ;
609
603
}
610
604
bool LookupSubNet (const char * pszName, CSubNet& ret)
0 commit comments