From 3781c2419c8e9b4b2f37e4317519f142efc1768d Mon Sep 17 00:00:00 2001 From: Roger Meier Date: Sun, 11 Dec 2011 20:07:21 +0000 Subject: [PATCH] THRIFT-1337 support maximum frame size in TNonblockingServer Patch: Dave Watson git-svn-id: https://svn.apache.org/repos/asf/thrift/trunk@1213052 13f79535-47bb-0310-9956-ffa450edef68 --- lib/cpp/src/server/TNonblockingServer.cpp | 14 +++++++++--- lib/cpp/src/server/TNonblockingServer.h | 28 +++++++++++++++++++++++ 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/lib/cpp/src/server/TNonblockingServer.cpp b/lib/cpp/src/server/TNonblockingServer.cpp index e8d0e713..0e44ab2b 100644 --- a/lib/cpp/src/server/TNonblockingServer.cpp +++ b/lib/cpp/src/server/TNonblockingServer.cpp @@ -17,6 +17,8 @@ * under the License. */ +#define __STDC_FORMAT_MACROS + #ifdef HAVE_CONFIG_H #include #endif @@ -435,7 +437,7 @@ void TNonblockingServer::TConnection::workSocket() { case SOCKET_RECV_FRAMING: union { uint8_t buf[sizeof(uint32_t)]; - int32_t size; + uint32_t size; } framing; // if we've already received some bytes we kept them here @@ -465,8 +467,14 @@ void TNonblockingServer::TConnection::workSocket() { } readWant_ = ntohl(framing.size); - if (static_cast(readWant_) <= 0) { - GlobalOutput.printf("TConnection:workSocket() Negative frame size %d, remote side not using TFramedTransport?", static_cast(readWant_)); + if (readWant_ > server_->getMaxFrameSize()) { + // Don't allow giant frame sizes. This prevents bad clients from + // causing us to try and allocate a giant buffer. + GlobalOutput.printf("TNonblockingServer: frame size too large " + "(%"PRIu32" > %zu) from client %s. remote side not " + "using TFramedTransport?", + readWant_, server_->getMaxFrameSize(), + tSocket_->getSocketInfo().c_str()); close(); return; } diff --git a/lib/cpp/src/server/TNonblockingServer.h b/lib/cpp/src/server/TNonblockingServer.h index 9eedcee0..e5d33119 100644 --- a/lib/cpp/src/server/TNonblockingServer.h +++ b/lib/cpp/src/server/TNonblockingServer.h @@ -121,6 +121,9 @@ class TNonblockingServer : public TServer { /// Default limit on size of idle connection pool static const size_t CONNECTION_STACK_LIMIT = 1024; + /// Default limit on frame size + static const int MAX_FRAME_SIZE = 256 * 1024 * 1024; + /// Default limit on total number of connected sockets static const int MAX_CONNECTIONS = INT_MAX; @@ -190,6 +193,9 @@ class TNonblockingServer : public TServer { /// Limit for number of open connections size_t maxConnections_; + /// Limit for frame size + size_t maxFrameSize_; + /// Time in milliseconds before an unperformed task expires (0 == infinite). int64_t taskExpireTime_; @@ -271,6 +277,7 @@ class TNonblockingServer : public TServer { connectionStackLimit_ = CONNECTION_STACK_LIMIT; maxActiveProcessors_ = MAX_ACTIVE_PROCESSORS; maxConnections_ = MAX_CONNECTIONS; + maxFrameSize_ = MAX_FRAME_SIZE; taskExpireTime_ = 0; overloadHysteresis_ = 0.8; overloadAction_ = T_OVERLOAD_NO_ACTION; @@ -518,6 +525,27 @@ class TNonblockingServer : public TServer { maxActiveProcessors_ = maxActiveProcessors; } + /** + * Get the maximum allowed frame size. + * + * If a client tries to send a message larger than this limit, + * its connection will be closed. + * + * @return Maxium frame size, in bytes. + */ + size_t getMaxFrameSize() const { + return maxFrameSize_; + } + + /** + * Set the maximum allowed frame size. + * + * @param maxFrameSize The new maximum frame size. + */ + void setMaxFrameSize(size_t maxFrameSize) { + maxFrameSize_ = maxFrameSize; + } + /** * Get fraction of maximum limits before an overload condition is cleared. * -- 2.17.1