|
7 | 7 | #include "bitcoin-config.h"
|
8 | 8 | #endif
|
9 | 9 |
|
10 |
| -#ifdef HAVE_GETADDRINFO_A |
11 |
| -#include <netdb.h> |
12 |
| -#endif |
13 |
| - |
14 | 10 | #include "netbase.h"
|
15 | 11 |
|
16 | 12 | #include "hash.h"
|
17 | 13 | #include "sync.h"
|
18 | 14 | #include "uint256.h"
|
19 | 15 | #include "util.h"
|
20 | 16 |
|
| 17 | +#ifdef HAVE_GETADDRINFO_A |
| 18 | +#include <netdb.h> |
| 19 | +#endif |
| 20 | + |
21 | 21 | #ifndef WIN32
|
22 | 22 | #if HAVE_INET_PTON
|
23 | 23 | #include <arpa/inet.h>
|
@@ -331,22 +331,15 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe
|
331 | 331 | SOCKET hSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
|
332 | 332 | if (hSocket == INVALID_SOCKET)
|
333 | 333 | return false;
|
| 334 | + |
334 | 335 | #ifdef SO_NOSIGPIPE
|
335 | 336 | int set = 1;
|
336 | 337 | setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
|
337 | 338 | #endif
|
338 | 339 |
|
339 |
| -#ifdef WIN32 |
340 |
| - u_long fNonblock = 1; |
341 |
| - if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR) |
342 |
| -#else |
343 |
| - int fFlags = fcntl(hSocket, F_GETFL, 0); |
344 |
| - if (fcntl(hSocket, F_SETFL, fFlags | O_NONBLOCK) == -1) |
345 |
| -#endif |
346 |
| - { |
347 |
| - CloseSocket(hSocket); |
348 |
| - return false; |
349 |
| - } |
| 340 | + // Set to non-blocking |
| 341 | + if (!SetSocketNonBlocking(hSocket, true)) |
| 342 | + return error("ConnectSocketDirectly: Setting socket to non-blocking failed, error %s\n", NetworkErrorString(WSAGetLastError())); |
350 | 343 |
|
351 | 344 | if (connect(hSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
|
352 | 345 | {
|
@@ -404,20 +397,10 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe
|
404 | 397 | }
|
405 | 398 | }
|
406 | 399 |
|
407 |
| - // this isn't even strictly necessary |
408 |
| - // CNode::ConnectNode immediately turns the socket back to non-blocking |
409 |
| - // but we'll turn it back to blocking just in case |
410 |
| -#ifdef WIN32 |
411 |
| - fNonblock = 0; |
412 |
| - if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR) |
413 |
| -#else |
414 |
| - fFlags = fcntl(hSocket, F_GETFL, 0); |
415 |
| - if (fcntl(hSocket, F_SETFL, fFlags & ~O_NONBLOCK) == SOCKET_ERROR) |
416 |
| -#endif |
417 |
| - { |
418 |
| - CloseSocket(hSocket); |
419 |
| - return false; |
420 |
| - } |
| 400 | + // This is required when using SOCKS5 proxy! |
| 401 | + // CNode::ConnectNode turns the socket back to non-blocking. |
| 402 | + if (!SetSocketNonBlocking(hSocket, false)) |
| 403 | + return error("ConnectSocketDirectly: Setting socket to blocking failed, error %s\n", NetworkErrorString(WSAGetLastError())); |
421 | 404 |
|
422 | 405 | hSocketRet = hSocket;
|
423 | 406 | return true;
|
@@ -1271,3 +1254,32 @@ bool CloseSocket(SOCKET& hSocket)
|
1271 | 1254 | hSocket = INVALID_SOCKET;
|
1272 | 1255 | return ret != SOCKET_ERROR;
|
1273 | 1256 | }
|
| 1257 | + |
| 1258 | +bool SetSocketNonBlocking(SOCKET& hSocket, bool fNonBlocking) |
| 1259 | +{ |
| 1260 | + if (fNonBlocking) { |
| 1261 | +#ifdef WIN32 |
| 1262 | + u_long nOne = 1; |
| 1263 | + if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR) { |
| 1264 | +#else |
| 1265 | + int fFlags = fcntl(hSocket, F_GETFL, 0); |
| 1266 | + if (fcntl(hSocket, F_SETFL, fFlags | O_NONBLOCK) == SOCKET_ERROR) { |
| 1267 | +#endif |
| 1268 | + CloseSocket(hSocket); |
| 1269 | + return false; |
| 1270 | + } |
| 1271 | + } else { |
| 1272 | +#ifdef WIN32 |
| 1273 | + u_long nZero = 0; |
| 1274 | + if (ioctlsocket(hSocket, FIONBIO, &nZero) == SOCKET_ERROR) { |
| 1275 | +#else |
| 1276 | + int fFlags = fcntl(hSocket, F_GETFL, 0); |
| 1277 | + if (fcntl(hSocket, F_SETFL, fFlags & ~O_NONBLOCK) == SOCKET_ERROR) { |
| 1278 | +#endif |
| 1279 | + CloseSocket(hSocket); |
| 1280 | + return false; |
| 1281 | + } |
| 1282 | + } |
| 1283 | + |
| 1284 | + return true; |
| 1285 | +} |
0 commit comments