curl-fuzzer C++ reference
Loading...
Searching...
No Matches
proto_fuzzer::FtpMockServer Class Reference

Keeps FTP's control and passive/active data connections alive. More...

#include <ftp_mock_server.h>

Inheritance diagram for proto_fuzzer::FtpMockServer:
proto_fuzzer::MockServerBase proto_fuzzer::IncomingDataObserver proto_fuzzer::FtpsMockServer

Public Member Functions

 FtpMockServer ()
 Begin without a borrowed protobuf or open socketpairs.
 ~FtpMockServer () override
 Release server-owned descriptors and socketpair peers after curl has returned its client fds.
void ObserveState () override
 Retain protocol outcomes in coverage and introspector builds.
const std::string & control_transcript () const
 Expose the bounded command capture from the most recent drive so tests can verify FTP states without coupling assertions to curl debug output.
const std::string & uploaded_data () const
 Expose a bounded upload prefix from the most recent drive while continuing to drain all client bytes, so test observability cannot create backpressure.
std::size_t opened_data_connection_count () const
 Report how many bounded data scripts curl assigned to passive or active transfer sockets, rather than how many scripts the protobuf contains.
std::size_t active_pollset_probe_count () const
 Report how many requested zero-timeout multi-poll probes ran during the most recent drive.
Public Member Functions inherited from proto_fuzzer::MockServerBase
virtual ~MockServerBase ()
 Out-of-line destructor so MockConnection can stay forward-declared in the base header (its complete type is only needed where unique_ptr is instantiated for destruction).
virtual void Install (CURL *easy)
 Install the common OPENSOCKETFUNCTION / OPENSOCKETDATA / SOCKOPTFUNCTION callbacks on 'easy'.
virtual void ConfigureRequestData (ScenarioRequestData *request_data)
 Bind protocol-specific work to the request-data callbacks after their per-scenario state has been constructed.
CURLcode DriveScenario (CURL *easy, const curl::fuzzer::proto::Scenario &scenario)
 Run 'scenario' to completion on 'easy': allocate a multi, attach 'easy', delegate protocol-specific work to RunLoop, consume its completion message, and clean up.
virtual CURLcode DriveEasyScenario (CURL *easy, const curl::fuzzer::proto::Scenario &scenario, bool use_events=false)
 Run through the public easy entrypoint when a protocol mock can preload all peer work before curl takes control.
virtual ConnectOnlyRunStats DriveConnectOnlyScenario (CURL *easy, const curl::fuzzer::proto::Scenario &scenario)
 Establish a CONNECT_ONLY transport, then perform bounded direct I/O.
void SetMultiObserver (MultiObserver observer)
 Register an observer invoked with the live multi handle after 'easy' is attached and before the drive loop starts.
MockConnection * connection ()

Protected Member Functions

virtual std::unique_ptr< MockConnection > CreateConnection ()
 Create the default plaintext transport for the control and passive data connections.
virtual bool SupportsActiveMode () const
 Plain FTP can create and publish a real loopback listener for PORT/EPRT.
void ReleaseConnections ()
 Close every server-owned transport before the borrowed scenario or a subclass transport disappears.
void ObserveIncomingData (const unsigned char *data, std::size_t size) override
 Retain decoded client bytes for the control parser.
curl_socket_t HandleOpenSocket (curlsocktype purpose=CURLSOCKTYPE_IPCXN, struct curl_sockaddr *address=nullptr) override
 Allocate one control socket followed by a bounded sequence of passive data sockets, or a real listener when CURLOPT_FTPPORT selected active mode.
SocketSetupDisposition GetSocketSetupDisposition (curl_socket_t curlfd, curlsocktype purpose) const override
 Control/passive sockets are connected AF_UNIX pairs, while active FTP needs curl to bind and listen on the real TCP descriptor returned by OpenActiveListener.
void RunLoop (CURLM *multi, CURL *easy, const curl::fuzzer::proto::Scenario &scenario) override
 Alternate curl transitions with immediate peer service until the transfer completes or deterministic idle/operation caps win.
Protected Member Functions inherited from proto_fuzzer::MockServerBase
 MockServerBase (MultiDrivePolicy drive_policy=MultiDrivePolicy::kPerform)
 Construct an empty base instance with a fixed multi-drive policy.
virtual void HandleDetachedMulti (CurlMultiPtr multi)
 Dispose of or retain the multi after its easy handle has been removed.
MultiSocketDriver * multi_socket_driver ()
 Expose the callback state installed for the current socket-action drive.
std::size_t additional_handle_cleanup_count () const
void ResumeResponseIfRequested (CURL *easy)
 Resume receive-side callback output at one bounded drive boundary when the dedicated API plan requested it.
void ApplyPendingBackpressure ()
 Apply the BackpressureConfig cached by DriveScenario to the new connection_.

Additional Inherited Members

Public Types inherited from proto_fuzzer::MockServerBase
using MultiObserver = std::function<void(CURLM*)>
 Callback type used to publish the driving multi handle to observers.
Static Protected Member Functions inherited from proto_fuzzer::MockServerBase
static int WaitOnMultiFdset (CURLM *multi, CURLMcode *rc)
 Wait on curl's fdset with a short timeout.
static void ProbeMultiPollset (CURLM *multi)
 Ask curl to construct and inspect its connection-filter pollset without waiting.
static bool MultiPollsetWantsWrite (CURLM *multi, curl_socket_t socket)
 Inspect one socket's current writable interest through curl's public multi fdset API.
static bool UsesTimedDrive (const curl::fuzzer::proto::Scenario &scenario)
 Treat a non-default BackpressureConfig as an explicit request for the slower, timed drive policy.
Protected Attributes inherited from proto_fuzzer::MockServerBase
std::unique_ptr< MockConnection > connection_
 The per-scenario MockConnection, lazily created by HandleOpenSocket().
int pending_recv_buf_bytes_
 Cached SO_RCVBUF/SO_SNDBUF setting in bytes.
std::size_t pending_drain_limit_
 Cached per-call DrainIncoming byte budget.
MultiSocketDriver * multi_socket_driver_
 Non-owning pointer into DriveScenario's stack.
std::size_t additional_handle_cleanup_count_
 Number of application-created handles, excluding the caller's parent, successfully removed from the current multi and cleaned up.
bool resume_response_
 True only for an API-plan multi drive with its one-shot write callback.
MultiObserver multi_observer_
 Observer receiving the live multi handle at the start of a drive.
Static Protected Attributes inherited from proto_fuzzer::MockServerBase
static constexpr int kMaxDriveIterations = 512
 Hard operation budget for one scenario.
static constexpr int kMaxIdleIterations = 8
 Consecutive no-progress budget for ordinary scenarios.
static constexpr int kMaxTimedIdleIterations = 256
 Explicit backpressure scenarios get a larger idle budget and may use the short timed wait above.

Detailed Description

Keeps FTP's control and passive/active data connections alive.

FTP cannot use the generic one-script-per-socket HTTP peer: curl opens a passive data socket while it still needs the control socket for TYPE, SIZE, RETR/STOR, and the final transfer reply. This peer therefore treats Scenario.connection as a command-aligned control script and the bounded subsequent_connections prefix as data streams. Passive transfers use socketpairs; active transfers let curl create a loopback listener and have the mock connect to it after observing the generated PORT/EPRT command. Both directions are observed after transport decoding, so a subclass can replace every socketpair with a TLS carrier without changing the FTP state machine. All work remains in-process and non-waiting so malformed scripts terminate by operation budget or EOF rather than by curl's FTP response timeout.

Definition at line 43 of file ftp_mock_server.h.

Constructor & Destructor Documentation

◆ FtpMockServer()

proto_fuzzer::FtpMockServer::FtpMockServer ( )

Begin without a borrowed protobuf or open socketpairs.

RunLoop borrows a Scenario only for the synchronous DriveScenario call in which socket callbacks can run. Keeping all session state in the object avoids process globals that could leak one libFuzzer iteration's protocol position into the next.

Definition at line 37 of file ftp_mock_server.cc.

◆ ~FtpMockServer()

proto_fuzzer::FtpMockServer::~FtpMockServer ( )
override

Release server-owned descriptors and socketpair peers after curl has returned its client fds.

Loopback peers are unique_ptr-owned transports; the out-of-line destructor also permits MockConnection to remain forward-declared in the header.

Definition at line 52 of file ftp_mock_server.cc.

Member Function Documentation

◆ active_pollset_probe_count()

std::size_t proto_fuzzer::FtpMockServer::active_pollset_probe_count ( ) const

Report how many requested zero-timeout multi-poll probes ran during the most recent drive.

RunLoop increments this only after a successful perform turn while curl still owns an active transfer and the control socket is open.

Returns
Number of active FTP pollset probes in the previous drive.

Definition at line 112 of file ftp_mock_server.cc.

◆ control_transcript()

const std::string & proto_fuzzer::FtpMockServer::control_transcript ( ) const

Expose the bounded command capture from the most recent drive so tests can verify FTP states without coupling assertions to curl debug output.

The capture is bounded independently of protocol processing.

Returns
A prefix of complete control commands, including line endings.

Definition at line 94 of file ftp_mock_server.cc.

◆ CreateConnection()

std::unique_ptr< MockConnection > proto_fuzzer::FtpMockServer::CreateConnection ( )
protectedvirtual

Create the default plaintext transport for the control and passive data connections.

The implicit-TLS FTPS subclass overrides this factory while retaining the command parser and channel bookkeeping.

Returns
A new socketpair-backed connection.

Reimplemented in proto_fuzzer::FtpsMockServer.

Definition at line 58 of file ftp_mock_server.cc.

◆ GetSocketSetupDisposition()

SocketSetupDisposition proto_fuzzer::FtpMockServer::GetSocketSetupDisposition ( curl_socket_t curlfd,
curlsocktype purpose ) const
overrideprotectedvirtual

Control/passive sockets are connected AF_UNIX pairs, while active FTP needs curl to bind and listen on the real TCP descriptor returned by OpenActiveListener.

The descriptor identity is recorded when opened, so this decision never depends on a sandbox-sensitive getsockopt call.

Parameters
curlfdDescriptor returned by HandleOpenSocket.
purposeRole curl assigned to the descriptor.
Returns
Whether curl must perform its normal socket setup.

Reimplemented from proto_fuzzer::MockServerBase.

Definition at line 205 of file ftp_mock_server.cc.

◆ HandleOpenSocket()

curl_socket_t proto_fuzzer::FtpMockServer::HandleOpenSocket ( curlsocktype purpose = CURLSOCKTYPE_IPCXN,
struct curl_sockaddr * address = nullptr )
overrideprotectedvirtual

Allocate one control socket followed by a bounded sequence of passive data sockets, or a real listener when CURLOPT_FTPPORT selected active mode.

Data is intentionally not preloaded here: curl has not yet sent the command that determines whether the stream is a listing, download, or upload.

Parameters
purposeSocket role requested by curl.
addressMutable description of curl's intended destination.
Returns
Client descriptor for the selected FTP channel, or CURL_SOCKET_BAD when no channel is available.

Implements proto_fuzzer::MockServerBase.

Definition at line 259 of file ftp_mock_server.cc.

◆ ObserveIncomingData()

void proto_fuzzer::FtpMockServer::ObserveIncomingData ( const unsigned char * data,
std::size_t size )
overrideprotectedvirtual

Retain decoded client bytes for the control parser.

Data channels install their own observer so upload bodies are routed without mixing them into the command stream.

Parameters
dataFirst decoded byte.
sizeNumber of bytes available at data.

Implements proto_fuzzer::IncomingDataObserver.

Definition at line 71 of file ftp_mock_server.cc.

◆ opened_data_connection_count()

std::size_t proto_fuzzer::FtpMockServer::opened_data_connection_count ( ) const

Report how many bounded data scripts curl assigned to passive or active transfer sockets, rather than how many scripts the protobuf contains.

Tests can distinguish control-only failures from paths that reached data setup.

Returns
Number of bounded data scripts assigned to a transfer socket.

Definition at line 105 of file ftp_mock_server.cc.

◆ ReleaseConnections()

void proto_fuzzer::FtpMockServer::ReleaseConnections ( )
protected

Close every server-owned transport before the borrowed scenario or a subclass transport disappears.

The out-of-line definition keeps MockConnection complete here while the header only forward-declares it.

Definition at line 117 of file ftp_mock_server.cc.

◆ RunLoop()

void proto_fuzzer::FtpMockServer::RunLoop ( CURLM * multi,
CURL * easy,
const curl::fuzzer::proto::Scenario & scenario )
overrideprotectedvirtual

Alternate curl transitions with immediate peer service until the transfer completes or deterministic idle/operation caps win.

No select(), poll(), or sleep is needed: every transport is in-process, and malformed scripts are terminated by half-close after the bounded loop.

Parameters
multiMulti handle containing easy.
easyEasy handle already installed on this mock.
scenarioControl and passive-data scripts to borrow.

Implements proto_fuzzer::MockServerBase.

Definition at line 795 of file ftp_mock_server.cc.

◆ SupportsActiveMode()

bool proto_fuzzer::FtpMockServer::SupportsActiveMode ( ) const
protectedvirtual

Plain FTP can create and publish a real loopback listener for PORT/EPRT.

Subclasses that only expose wrapped socketpairs override this to keep the active-mode request from producing an unusable plaintext endpoint.

Returns
true for the plaintext FTP peer.

Reimplemented in proto_fuzzer::FtpsMockServer.

Definition at line 64 of file ftp_mock_server.cc.

◆ uploaded_data()

const std::string & proto_fuzzer::FtpMockServer::uploaded_data ( ) const

Expose a bounded upload prefix from the most recent drive while continuing to drain all client bytes, so test observability cannot create backpressure.

Returns
Bytes curl sent over passive upload connections.

Definition at line 99 of file ftp_mock_server.cc.


The documentation for this class was generated from the following files: