Browse Source

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)
0.8
Gavin Andresen 14 years ago
parent
commit
9cbae55a6e
  1. 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…
Cancel
Save