diff options
author | Gavin Andresen <gavinandresen@gmail.com> | 2011-02-16 13:18:11 -0500 |
---|---|---|
committer | Gavin Andresen <gavinandresen@gmail.com> | 2011-02-16 13:18:11 -0500 |
commit | 9cbae55a6ed6fcc46e636b4ae670816aab3746ec (patch) | |
tree | 0151584a07bced17758f2eb40f6a7271af68ed7c | |
parent | cf7c1874fead05a828a1a28a239da411a0cb725e (diff) |
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)
-rw-r--r-- | net.cpp | 50 |
1 files changed, 31 insertions, 19 deletions
@@ -748,32 +748,39 @@ void ThreadSocketHandler2(void* parg) CDataStream& vRecv = pnode->vRecv; unsigned int nPos = vRecv.size(); - // typical socket buffer is 8K-64K - 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 (nPos > 1000*GetArg("-maxreceivebuffer", 2*1000)) { if (!pnode->fDisconnect) - printf("socket closed\n"); + printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size()); pnode->CloseSocketDisconnect(); } - else if (nBytes < 0) - { - // error - int nErr = WSAGetLastError(); - if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS) + else { + // typical socket buffer is 8K-64K + 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) - printf("socket recv error %d\n", nErr); + printf("socket closed\n"); 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(); } } + if (vSend.size() > 1000*GetArg("-maxsendbuffer", 256)) { + if (!pnode->fDisconnect) + printf("socket send flood control disconnect (%d bytes)\n", vSend.size()); + pnode->CloseSocketDisconnect(); + } } } } |