Browse Source

Merge pull request #4491

eaedb59 net: add SetSocketNonBlocking() as OS independent wrapper (Philip Kaufmann)
0.10
Wladimir J. van der Laan 10 years ago
parent
commit
c5eabde9ea
No known key found for this signature in database
GPG Key ID: 74810B012346C9A6
  1. 19
      src/net.cpp
  2. 70
      src/netbase.cpp
  3. 2
      src/netbase.h

19
src/net.cpp

@ -501,14 +501,8 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest)
addrman.Attempt(addrConnect); addrman.Attempt(addrConnect);
// Set to non-blocking // Set to non-blocking
#ifdef WIN32 if (!SetSocketNonBlocking(hSocket, true))
u_long nOne = 1; LogPrintf("ConnectNode: Setting socket to non-blocking failed, error %s\n", NetworkErrorString(WSAGetLastError()));
if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
LogPrintf("ConnectSocket() : ioctlsocket non-blocking setting failed, error %s\n", NetworkErrorString(WSAGetLastError()));
#else
if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
LogPrintf("ConnectSocket() : fcntl non-blocking setting failed, error %s\n", NetworkErrorString(errno));
#endif
// Add node // Add node
CNode* pnode = new CNode(hSocket, addrConnect, pszDest ? pszDest : "", false); CNode* pnode = new CNode(hSocket, addrConnect, pszDest ? pszDest : "", false);
@ -1642,14 +1636,9 @@ bool BindListenPort(const CService &addrBind, string& strError, bool fWhiteliste
setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int)); setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
#endif #endif
#ifdef WIN32
// Set to non-blocking, incoming connections will also inherit this // Set to non-blocking, incoming connections will also inherit this
if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR) if (!SetSocketNonBlocking(hListenSocket, true)) {
#else strError = strprintf("BindListenPort: Setting listening socket to non-blocking failed, error %s\n", NetworkErrorString(WSAGetLastError()));
if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
#endif
{
strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %s)", NetworkErrorString(WSAGetLastError()));
LogPrintf("%s\n", strError); LogPrintf("%s\n", strError);
return false; return false;
} }

70
src/netbase.cpp

@ -7,10 +7,6 @@
#include "bitcoin-config.h" #include "bitcoin-config.h"
#endif #endif
#ifdef HAVE_GETADDRINFO_A
#include <netdb.h>
#endif
#include "netbase.h" #include "netbase.h"
#include "hash.h" #include "hash.h"
@ -18,6 +14,10 @@
#include "uint256.h" #include "uint256.h"
#include "util.h" #include "util.h"
#ifdef HAVE_GETADDRINFO_A
#include <netdb.h>
#endif
#ifndef WIN32 #ifndef WIN32
#if HAVE_INET_PTON #if HAVE_INET_PTON
#include <arpa/inet.h> #include <arpa/inet.h>
@ -331,22 +331,15 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe
SOCKET hSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP); SOCKET hSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
if (hSocket == INVALID_SOCKET) if (hSocket == INVALID_SOCKET)
return false; return false;
#ifdef SO_NOSIGPIPE #ifdef SO_NOSIGPIPE
int set = 1; int set = 1;
setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int)); setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
#endif #endif
#ifdef WIN32 // Set to non-blocking
u_long fNonblock = 1; if (!SetSocketNonBlocking(hSocket, true))
if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR) return error("ConnectSocketDirectly: Setting socket to non-blocking failed, error %s\n", NetworkErrorString(WSAGetLastError()));
#else
int fFlags = fcntl(hSocket, F_GETFL, 0);
if (fcntl(hSocket, F_SETFL, fFlags | O_NONBLOCK) == -1)
#endif
{
CloseSocket(hSocket);
return false;
}
if (connect(hSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR) if (connect(hSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
{ {
@ -404,20 +397,10 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe
} }
} }
// this isn't even strictly necessary // This is required when using SOCKS5 proxy!
// CNode::ConnectNode immediately turns the socket back to non-blocking // CNode::ConnectNode turns the socket back to non-blocking.
// but we'll turn it back to blocking just in case if (!SetSocketNonBlocking(hSocket, false))
#ifdef WIN32 return error("ConnectSocketDirectly: Setting socket to blocking failed, error %s\n", NetworkErrorString(WSAGetLastError()));
fNonblock = 0;
if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR)
#else
fFlags = fcntl(hSocket, F_GETFL, 0);
if (fcntl(hSocket, F_SETFL, fFlags & ~O_NONBLOCK) == SOCKET_ERROR)
#endif
{
CloseSocket(hSocket);
return false;
}
hSocketRet = hSocket; hSocketRet = hSocket;
return true; return true;
@ -1271,3 +1254,32 @@ bool CloseSocket(SOCKET& hSocket)
hSocket = INVALID_SOCKET; hSocket = INVALID_SOCKET;
return ret != SOCKET_ERROR; return ret != SOCKET_ERROR;
} }
bool SetSocketNonBlocking(SOCKET& hSocket, bool fNonBlocking)
{
if (fNonBlocking) {
#ifdef WIN32
u_long nOne = 1;
if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR) {
#else
int fFlags = fcntl(hSocket, F_GETFL, 0);
if (fcntl(hSocket, F_SETFL, fFlags | O_NONBLOCK) == SOCKET_ERROR) {
#endif
CloseSocket(hSocket);
return false;
}
} else {
#ifdef WIN32
u_long nZero = 0;
if (ioctlsocket(hSocket, FIONBIO, &nZero) == SOCKET_ERROR) {
#else
int fFlags = fcntl(hSocket, F_GETFL, 0);
if (fcntl(hSocket, F_SETFL, fFlags & ~O_NONBLOCK) == SOCKET_ERROR) {
#endif
CloseSocket(hSocket);
return false;
}
}
return true;
}

2
src/netbase.h

@ -180,5 +180,7 @@ bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest
std::string NetworkErrorString(int err); std::string NetworkErrorString(int err);
/** Close socket and set hSocket to INVALID_SOCKET */ /** Close socket and set hSocket to INVALID_SOCKET */
bool CloseSocket(SOCKET& hSocket); bool CloseSocket(SOCKET& hSocket);
/** Disable or enable blocking-mode for a socket */
bool SetSocketNonBlocking(SOCKET& hSocket, bool fNonBlocking);
#endif #endif

Loading…
Cancel
Save