aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGavin Andresen <gavinandresen@gmail.com>2011-02-16 13:18:11 -0500
committerGavin Andresen <gavinandresen@gmail.com>2011-02-16 13:18:11 -0500
commit9cbae55a6ed6fcc46e636b4ae670816aab3746ec (patch)
tree0151584a07bced17758f2eb40f6a7271af68ed7c
parentcf7c1874fead05a828a1a28a239da411a0cb725e (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.cpp50
1 files changed, 31 insertions, 19 deletions
diff --git a/net.cpp b/net.cpp
index 816c7e3480..8480a2fcf4 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();
+ }
}
}
}