mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 12:02:48 +01:00
Replace non-threadsafe strerror
Log the name of the error as well as the error code if a network problem
happens. This makes network troubleshooting more convenient.
Use thread-safe strerror_r and the WIN32 equivalent FormatMessage.
Conflicts:
src/netbase.cpp
Rebased-By: Wladimir van der Laan <laanwj@gmail.com>
Rebased-From: a60838d
This commit is contained in:
parent
2585310a22
commit
e0036e9f0e
@ -303,6 +303,8 @@ INCLUDES="$INCLUDES $PTHREAD_CFLAGS"
|
|||||||
# they also need to be passed down to any subprojects. Pull the results out of
|
# they also need to be passed down to any subprojects. Pull the results out of
|
||||||
# the cache and add them to CPPFLAGS.
|
# the cache and add them to CPPFLAGS.
|
||||||
AC_SYS_LARGEFILE
|
AC_SYS_LARGEFILE
|
||||||
|
# detect POSIX or GNU variant of strerror_r
|
||||||
|
AC_FUNC_STRERROR_R
|
||||||
|
|
||||||
if test x$ac_cv_sys_file_offset_bits != x &&
|
if test x$ac_cv_sys_file_offset_bits != x &&
|
||||||
test x$ac_cv_sys_file_offset_bits != xno &&
|
test x$ac_cv_sys_file_offset_bits != xno &&
|
||||||
|
24
src/net.cpp
24
src/net.cpp
@ -178,7 +178,7 @@ bool RecvLine(SOCKET hSocket, string& strLine)
|
|||||||
{
|
{
|
||||||
// socket error
|
// socket error
|
||||||
int nErr = WSAGetLastError();
|
int nErr = WSAGetLastError();
|
||||||
LogPrint("net", "recv failed: %d\n", nErr);
|
LogPrint("net", "recv failed: %s\n", NetworkErrorString(nErr));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -489,10 +489,10 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest)
|
|||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
u_long nOne = 1;
|
u_long nOne = 1;
|
||||||
if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
|
if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
|
||||||
LogPrintf("ConnectSocket() : ioctlsocket non-blocking setting failed, error %d\n", WSAGetLastError());
|
LogPrintf("ConnectSocket() : ioctlsocket non-blocking setting failed, error %s\n", NetworkErrorString(WSAGetLastError()));
|
||||||
#else
|
#else
|
||||||
if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
|
if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
|
||||||
LogPrintf("ConnectSocket() : fcntl non-blocking setting failed, error %d\n", errno);
|
LogPrintf("ConnectSocket() : fcntl non-blocking setting failed, error %s\n", NetworkErrorString(errno));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Add node
|
// Add node
|
||||||
@ -736,7 +736,7 @@ void SocketSendData(CNode *pnode)
|
|||||||
int nErr = WSAGetLastError();
|
int nErr = WSAGetLastError();
|
||||||
if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
|
if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
|
||||||
{
|
{
|
||||||
LogPrintf("socket send error %d\n", nErr);
|
LogPrintf("socket send error %s\n", NetworkErrorString(nErr));
|
||||||
pnode->CloseSocketDisconnect();
|
pnode->CloseSocketDisconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -896,7 +896,7 @@ void ThreadSocketHandler()
|
|||||||
if (have_fds)
|
if (have_fds)
|
||||||
{
|
{
|
||||||
int nErr = WSAGetLastError();
|
int nErr = WSAGetLastError();
|
||||||
LogPrintf("socket select error %d\n", nErr);
|
LogPrintf("socket select error %s\n", NetworkErrorString(nErr));
|
||||||
for (unsigned int i = 0; i <= hSocketMax; i++)
|
for (unsigned int i = 0; i <= hSocketMax; i++)
|
||||||
FD_SET(i, &fdsetRecv);
|
FD_SET(i, &fdsetRecv);
|
||||||
}
|
}
|
||||||
@ -933,7 +933,7 @@ void ThreadSocketHandler()
|
|||||||
{
|
{
|
||||||
int nErr = WSAGetLastError();
|
int nErr = WSAGetLastError();
|
||||||
if (nErr != WSAEWOULDBLOCK)
|
if (nErr != WSAEWOULDBLOCK)
|
||||||
LogPrintf("socket error accept failed: %d\n", nErr);
|
LogPrintf("socket error accept failed: %s\n", NetworkErrorString(nErr));
|
||||||
}
|
}
|
||||||
else if (nInbound >= nMaxConnections - MAX_OUTBOUND_CONNECTIONS)
|
else if (nInbound >= nMaxConnections - MAX_OUTBOUND_CONNECTIONS)
|
||||||
{
|
{
|
||||||
@ -1007,7 +1007,7 @@ void ThreadSocketHandler()
|
|||||||
if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
|
if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
|
||||||
{
|
{
|
||||||
if (!pnode->fDisconnect)
|
if (!pnode->fDisconnect)
|
||||||
LogPrintf("socket recv error %d\n", nErr);
|
LogPrintf("socket recv error %s\n", NetworkErrorString(nErr));
|
||||||
pnode->CloseSocketDisconnect();
|
pnode->CloseSocketDisconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1585,7 +1585,7 @@ bool BindListenPort(const CService &addrBind, string& strError)
|
|||||||
SOCKET hListenSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
|
SOCKET hListenSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
|
||||||
if (hListenSocket == INVALID_SOCKET)
|
if (hListenSocket == INVALID_SOCKET)
|
||||||
{
|
{
|
||||||
strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
|
strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %s)", NetworkErrorString(WSAGetLastError()));
|
||||||
LogPrintf("%s\n", strError);
|
LogPrintf("%s\n", strError);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1609,7 +1609,7 @@ bool BindListenPort(const CService &addrBind, string& strError)
|
|||||||
if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
|
if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
|
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;
|
||||||
}
|
}
|
||||||
@ -1638,7 +1638,7 @@ bool BindListenPort(const CService &addrBind, string& strError)
|
|||||||
if (nErr == WSAEADDRINUSE)
|
if (nErr == WSAEADDRINUSE)
|
||||||
strError = strprintf(_("Unable to bind to %s on this computer. Bitcoin Core is probably already running."), addrBind.ToString());
|
strError = strprintf(_("Unable to bind to %s on this computer. Bitcoin Core is probably already running."), addrBind.ToString());
|
||||||
else
|
else
|
||||||
strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %d, %s)"), addrBind.ToString(), nErr, strerror(nErr));
|
strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %s)"), addrBind.ToString(), NetworkErrorString(nErr));
|
||||||
LogPrintf("%s\n", strError);
|
LogPrintf("%s\n", strError);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1647,7 +1647,7 @@ bool BindListenPort(const CService &addrBind, string& strError)
|
|||||||
// Listen for incoming connections
|
// Listen for incoming connections
|
||||||
if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
|
if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
|
||||||
{
|
{
|
||||||
strError = strprintf(_("Error: Listening for incoming connections failed (listen returned error %d)"), WSAGetLastError());
|
strError = strprintf(_("Error: Listening for incoming connections failed (listen returned error %s)"), NetworkErrorString(WSAGetLastError()));
|
||||||
LogPrintf("%s\n", strError);
|
LogPrintf("%s\n", strError);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1785,7 +1785,7 @@ public:
|
|||||||
BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket)
|
BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket)
|
||||||
if (hListenSocket != INVALID_SOCKET)
|
if (hListenSocket != INVALID_SOCKET)
|
||||||
if (closesocket(hListenSocket) == SOCKET_ERROR)
|
if (closesocket(hListenSocket) == SOCKET_ERROR)
|
||||||
LogPrintf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
|
LogPrintf("closesocket(hListenSocket) failed with error %s\n", NetworkErrorString(WSAGetLastError()));
|
||||||
|
|
||||||
// clean up some globals (to help leak detection)
|
// clean up some globals (to help leak detection)
|
||||||
BOOST_FOREACH(CNode *pnode, vNodes)
|
BOOST_FOREACH(CNode *pnode, vNodes)
|
||||||
|
@ -363,7 +363,7 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe
|
|||||||
}
|
}
|
||||||
if (nRet == SOCKET_ERROR)
|
if (nRet == SOCKET_ERROR)
|
||||||
{
|
{
|
||||||
LogPrintf("select() for %s failed: %i\n", addrConnect.ToString(), WSAGetLastError());
|
LogPrintf("select() for %s failed: %s\n", addrConnect.ToString(), NetworkErrorString(WSAGetLastError()));
|
||||||
closesocket(hSocket);
|
closesocket(hSocket);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -374,13 +374,13 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe
|
|||||||
if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, &nRet, &nRetSize) == SOCKET_ERROR)
|
if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, &nRet, &nRetSize) == SOCKET_ERROR)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
LogPrintf("getsockopt() for %s failed: %i\n", addrConnect.ToString(), WSAGetLastError());
|
LogPrintf("getsockopt() for %s failed: %s\n", addrConnect.ToString(), NetworkErrorString(WSAGetLastError()));
|
||||||
closesocket(hSocket);
|
closesocket(hSocket);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (nRet != 0)
|
if (nRet != 0)
|
||||||
{
|
{
|
||||||
LogPrintf("connect() to %s failed after select(): %s\n", addrConnect.ToString(), strerror(nRet));
|
LogPrintf("connect() to %s failed after select(): %s\n", addrConnect.ToString(), NetworkErrorString(nRet));
|
||||||
closesocket(hSocket);
|
closesocket(hSocket);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -391,7 +391,7 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe
|
|||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
LogPrintf("connect() to %s failed: %i\n", addrConnect.ToString(), WSAGetLastError());
|
LogPrintf("connect() to %s failed: %s\n", addrConnect.ToString(), NetworkErrorString(WSAGetLastError()));
|
||||||
closesocket(hSocket);
|
closesocket(hSocket);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1122,3 +1122,37 @@ void CService::SetPort(unsigned short portIn)
|
|||||||
{
|
{
|
||||||
port = portIn;
|
port = portIn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
std::string NetworkErrorString(int err)
|
||||||
|
{
|
||||||
|
char buf[256];
|
||||||
|
buf[0] = 0;
|
||||||
|
if(FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK,
|
||||||
|
NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
|
buf, sizeof(buf), NULL))
|
||||||
|
{
|
||||||
|
return strprintf("%s (%d)", buf, err);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return strprintf("Unknown error (%d)", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
std::string NetworkErrorString(int err)
|
||||||
|
{
|
||||||
|
char buf[256];
|
||||||
|
const char *s = buf;
|
||||||
|
buf[0] = 0;
|
||||||
|
/* Too bad there are two incompatible implementations of the
|
||||||
|
* thread-safe strerror. */
|
||||||
|
#ifdef STRERROR_R_CHAR_P /* GNU variant can return a pointer outside the passed buffer */
|
||||||
|
s = strerror_r(err, buf, sizeof(buf));
|
||||||
|
#else /* POSIX variant always returns message in buffer */
|
||||||
|
(void) strerror_r(err, buf, sizeof(buf));
|
||||||
|
#endif
|
||||||
|
return strprintf("%s (%d)", s, err);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@ -149,5 +149,7 @@ bool Lookup(const char *pszName, std::vector<CService>& vAddr, int portDefault =
|
|||||||
bool LookupNumeric(const char *pszName, CService& addr, int portDefault = 0);
|
bool LookupNumeric(const char *pszName, CService& addr, int portDefault = 0);
|
||||||
bool ConnectSocket(const CService &addr, SOCKET& hSocketRet, int nTimeout = nConnectTimeout);
|
bool ConnectSocket(const CService &addr, SOCKET& hSocketRet, int nTimeout = nConnectTimeout);
|
||||||
bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest, int portDefault = 0, int nTimeout = nConnectTimeout);
|
bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest, int portDefault = 0, int nTimeout = nConnectTimeout);
|
||||||
|
/** Return readable error string for a network error code */
|
||||||
|
std::string NetworkErrorString(int err);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user