Skip to content

Commit eaedb59

Browse files
author
Philip Kaufmann
committed
net: add SetSocketNonBlocking() as OS independent wrapper
1 parent e8d4cb8 commit eaedb59

File tree

3 files changed

+47
-44
lines changed

3 files changed

+47
-44
lines changed

src/net.cpp

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -501,14 +501,8 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest)
501501
addrman.Attempt(addrConnect);
502502

503503
// Set to non-blocking
504-
#ifdef WIN32
505-
u_long nOne = 1;
506-
if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
507-
LogPrintf("ConnectSocket() : ioctlsocket non-blocking setting failed, error %s\n", NetworkErrorString(WSAGetLastError()));
508-
#else
509-
if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
510-
LogPrintf("ConnectSocket() : fcntl non-blocking setting failed, error %s\n", NetworkErrorString(errno));
511-
#endif
504+
if (!SetSocketNonBlocking(hSocket, true))
505+
LogPrintf("ConnectNode: Setting socket to non-blocking failed, error %s\n", NetworkErrorString(WSAGetLastError()));
512506

513507
// Add node
514508
CNode* pnode = new CNode(hSocket, addrConnect, pszDest ? pszDest : "", false);
@@ -1642,14 +1636,9 @@ bool BindListenPort(const CService &addrBind, string& strError, bool fWhiteliste
16421636
setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
16431637
#endif
16441638

1645-
#ifdef WIN32
16461639
// Set to non-blocking, incoming connections will also inherit this
1647-
if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1648-
#else
1649-
if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1650-
#endif
1651-
{
1652-
strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %s)", NetworkErrorString(WSAGetLastError()));
1640+
if (!SetSocketNonBlocking(hListenSocket, true)) {
1641+
strError = strprintf("BindListenPort: Setting listening socket to non-blocking failed, error %s\n", NetworkErrorString(WSAGetLastError()));
16531642
LogPrintf("%s\n", strError);
16541643
return false;
16551644
}

src/netbase.cpp

Lines changed: 41 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,17 @@
77
#include "bitcoin-config.h"
88
#endif
99

10-
#ifdef HAVE_GETADDRINFO_A
11-
#include <netdb.h>
12-
#endif
13-
1410
#include "netbase.h"
1511

1612
#include "hash.h"
1713
#include "sync.h"
1814
#include "uint256.h"
1915
#include "util.h"
2016

17+
#ifdef HAVE_GETADDRINFO_A
18+
#include <netdb.h>
19+
#endif
20+
2121
#ifndef WIN32
2222
#if HAVE_INET_PTON
2323
#include <arpa/inet.h>
@@ -331,22 +331,15 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe
331331
SOCKET hSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
332332
if (hSocket == INVALID_SOCKET)
333333
return false;
334+
334335
#ifdef SO_NOSIGPIPE
335336
int set = 1;
336337
setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
337338
#endif
338339

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()));
350343

351344
if (connect(hSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
352345
{
@@ -404,20 +397,10 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe
404397
}
405398
}
406399

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()));
421404

422405
hSocketRet = hSocket;
423406
return true;
@@ -1271,3 +1254,32 @@ bool CloseSocket(SOCKET& hSocket)
12711254
hSocket = INVALID_SOCKET;
12721255
return ret != SOCKET_ERROR;
12731256
}
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+
}

src/netbase.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,5 +180,7 @@ bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest
180180
std::string NetworkErrorString(int err);
181181
/** Close socket and set hSocket to INVALID_SOCKET */
182182
bool CloseSocket(SOCKET& hSocket);
183+
/** Disable or enable blocking-mode for a socket */
184+
bool SetSocketNonBlocking(SOCKET& hSocket, bool fNonBlocking);
183185

184186
#endif

0 commit comments

Comments
 (0)