Jens Geyer created THRIFT-6183:
----------------------------------

             Summary: Use the library-wide default frame size in 
TNonblockingServer in the C++ library
                 Key: THRIFT-6183
                 URL: https://issues.apache.org/jira/browse/THRIFT-6183
             Project: Thrift
          Issue Type: Bug
          Components: C++ - Library
            Reporter: Jens Geyer


TNonblockingServer caps the frame it will accept from a connection at its own 
MAX_FRAME_SIZE (lib/cpp/src/thrift/server/TNonblockingServer.h:127), which has 
been 256 * 1024 * 1024 since THRIFT-1337 landed it in 2011 - years before 
TConfiguration existed. The library-wide default is 
TConfiguration::DEFAULT_MAX_FRAME_SIZE = 16384000, whose own comment reads 
"this value is used consistently across all Thrift libraries".

The two disagree by a factor of 16:

    TNonblockingServer::getMaxFrameSize()     268435456
    TConfiguration::DEFAULT_MAX_FRAME_SIZE     16384000

TConfiguration appears zero times in TNonblockingServer.h and 
TNonblockingServer.cpp, so the server neither reads a configured value nor 
inherits the default. It starts from its own constant, and only 
setMaxFrameSize() moves it.

That constant is what sizes the read buffer. TConnection::transition() resets 
the read buffer to the frame length the peer declared before any payload byte 
has arrived, so a four-byte length prefix at the server's own maximum decides 
the allocation. Measured on a Linux x86-64 build, one connection sending 
nothing but that prefix takes the process from a VmPeak of 145,880 kB to 
604,636 kB. MAX_CONNECTIONS defaults to INT_MAX.

Other bindings do not have this gap. Java's AbstractNonblockingServer takes its 
per-frame limit from trans_.getMaxFrameSize(), that is from TConfiguration, and 
keeps a separate aggregate read-buffer budget on top of it.

The change points TNonblockingServer::MAX_FRAME_SIZE at 
TConfiguration::DEFAULT_MAX_FRAME_SIZE. The constant is private, so this is not 
an API change, and setMaxFrameSize() still overrides it.

Compatibility: this lowers a shipped default. A deployment that accepts frames 
between 16,384,000 and 268,435,456 bytes on TNonblockingServer today and does 
not call setMaxFrameSize() will start closing those connections. Needs a 
release note.

Out of scope here, both worth their own tickets: TNonblockingServer still does 
not consult TConfiguration at all, which is a larger design change; and 
lib/cpp/src/thrift/transport/TBufferTransports.h:349 still carries a 256 MB 
TFramedTransport::DEFAULT_MAX_FRAME_SIZE that nothing reads any more, which is 
public API and is left alone here.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to