mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-25 18:53:23 -03:00
Denial-of-service flood control
Drop connections that are either sending messages too fast to handle or are processing messages so slowly data starts to back up. Adds two new options: -maxreceivebuffer Default: 2000 (2000*1000 bytes) -maxsendbuffer Default: 256 (256*1000 bytes)
This commit is contained in:
parent
cf7c1874fe
commit
9cbae55a6e
1 changed files with 31 additions and 19 deletions
50
net.cpp
50
net.cpp
|
@ -748,32 +748,39 @@ void ThreadSocketHandler2(void* parg)
|
||||||
CDataStream& vRecv = pnode->vRecv;
|
CDataStream& vRecv = pnode->vRecv;
|
||||||
unsigned int nPos = vRecv.size();
|
unsigned int nPos = vRecv.size();
|
||||||
|
|
||||||
// typical socket buffer is 8K-64K
|
if (nPos > 1000*GetArg("-maxreceivebuffer", 2*1000)) {
|
||||||
char pchBuf[0x10000];
|
|
||||||
int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
|
|
||||||
if (nBytes > 0)
|
|
||||||
{
|
|
||||||
vRecv.resize(nPos + nBytes);
|
|
||||||
memcpy(&vRecv[nPos], pchBuf, nBytes);
|
|
||||||
pnode->nLastRecv = GetTime();
|
|
||||||
}
|
|
||||||
else if (nBytes == 0)
|
|
||||||
{
|
|
||||||
// socket closed gracefully
|
|
||||||
if (!pnode->fDisconnect)
|
if (!pnode->fDisconnect)
|
||||||
printf("socket closed\n");
|
printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
|
||||||
pnode->CloseSocketDisconnect();
|
pnode->CloseSocketDisconnect();
|
||||||
}
|
}
|
||||||
else if (nBytes < 0)
|
else {
|
||||||
{
|
// typical socket buffer is 8K-64K
|
||||||
// error
|
char pchBuf[0x10000];
|
||||||
int nErr = WSAGetLastError();
|
int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
|
||||||
if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
|
if (nBytes > 0)
|
||||||
{
|
{
|
||||||
|
vRecv.resize(nPos + nBytes);
|
||||||
|
memcpy(&vRecv[nPos], pchBuf, nBytes);
|
||||||
|
pnode->nLastRecv = GetTime();
|
||||||
|
}
|
||||||
|
else if (nBytes == 0)
|
||||||
|
{
|
||||||
|
// socket closed gracefully
|
||||||
if (!pnode->fDisconnect)
|
if (!pnode->fDisconnect)
|
||||||
printf("socket recv error %d\n", nErr);
|
printf("socket closed\n");
|
||||||
pnode->CloseSocketDisconnect();
|
pnode->CloseSocketDisconnect();
|
||||||
}
|
}
|
||||||
|
else if (nBytes < 0)
|
||||||
|
{
|
||||||
|
// error
|
||||||
|
int nErr = WSAGetLastError();
|
||||||
|
if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
|
||||||
|
{
|
||||||
|
if (!pnode->fDisconnect)
|
||||||
|
printf("socket recv error %d\n", nErr);
|
||||||
|
pnode->CloseSocketDisconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -806,6 +813,11 @@ void ThreadSocketHandler2(void* parg)
|
||||||
pnode->CloseSocketDisconnect();
|
pnode->CloseSocketDisconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (vSend.size() > 1000*GetArg("-maxsendbuffer", 256)) {
|
||||||
|
if (!pnode->fDisconnect)
|
||||||
|
printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
|
||||||
|
pnode->CloseSocketDisconnect();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue