From 9cbae55a6ed6fcc46e636b4ae670816aab3746ec Mon Sep 17 00:00:00 2001 From: Gavin Andresen Date: Wed, 16 Feb 2011 13:18:11 -0500 Subject: [PATCH] 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) --- net.cpp | 50 +++++++++++++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/net.cpp b/net.cpp index 816c7e34..8480a2fc 100644 --- a/net.cpp +++ b/net.cpp @@ -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(); + } } } }