curl-fuzzer C++ reference
Loading...
Searching...
No Matches
mock_server_base.h
Go to the documentation of this file.
1/*
2 * Copyright (C) Max Dymond, <cmeister2@gmail.com>, et al.
3 *
4 * SPDX-License-Identifier: curl
5 */
6
12
13#ifndef PROTO_FUZZER_MOCK_SERVER_BASE_H_
14#define PROTO_FUZZER_MOCK_SERVER_BASE_H_
15
16#include <curl/curl.h>
17
18#include <cstddef>
19#include <functional>
20#include <memory>
21#include <utility>
22
23#include "curl_fuzzer.pb.h"
25
26namespace proto_fuzzer {
27
28class MockConnection;
31
37 kNeedsSetup,
38 kAlreadyConnected,
39};
40
45 CURLcode connect_result = CURLE_FAILED_INIT;
46 CURLcode send_result = CURLE_FAILED_INIT;
47 CURLcode recv_result = CURLE_FAILED_INIT;
48 std::size_t sent_bytes = 0;
49 std::size_t received_bytes = 0;
50};
51
58
67class MockServerBase {
68 public:
69 virtual ~MockServerBase();
70
71 MockServerBase(const MockServerBase&) = delete;
72 MockServerBase& operator=(const MockServerBase&) = delete;
73
74 virtual void ObserveState();
75
76 virtual void Install(CURL* easy);
77
78 virtual void ConfigureRequestData(ScenarioRequestData* request_data);
79
80 CURLcode DriveScenario(CURL* easy, const curl::fuzzer::proto::Scenario& scenario);
81
82 virtual CURLcode DriveEasyScenario(CURL* easy, const curl::fuzzer::proto::Scenario& scenario,
83 bool use_events = false);
84
85 virtual ConnectOnlyRunStats DriveConnectOnlyScenario(CURL* easy, const curl::fuzzer::proto::Scenario& scenario);
86
88 using MultiObserver = std::function<void(CURLM*)>;
89
95 void SetMultiObserver(MultiObserver observer) { multi_observer_ = std::move(observer); }
96
98
99 protected:
101
102 virtual void HandleDetachedMulti(CurlMultiPtr multi);
103
113 virtual curl_socket_t HandleOpenSocket(curlsocktype purpose, struct curl_sockaddr* address) = 0;
114
115 virtual SocketSetupDisposition GetSocketSetupDisposition(curl_socket_t curlfd, curlsocktype purpose) const;
116
122 virtual void RunLoop(CURLM* multi, CURL* easy, const curl::fuzzer::proto::Scenario& scenario) = 0;
123
124 static int WaitOnMultiFdset(CURLM* multi, CURLMcode* rc);
125
126 static void ProbeMultiPollset(CURLM* multi);
127
128 // Ask curl whether one live socket currently needs writable readiness.
129 static bool MultiPollsetWantsWrite(CURLM* multi, curl_socket_t socket);
130
132
133 std::size_t additional_handle_cleanup_count() const;
134
135 void ResumeResponseIfRequested(CURL* easy);
136
140 static constexpr int kMaxDriveIterations = 512;
141
145 static constexpr int kMaxIdleIterations = 8;
146
150 static constexpr int kMaxTimedIdleIterations = 256;
151
152 static bool UsesTimedDrive(const curl::fuzzer::proto::Scenario& scenario);
153
155
158 std::unique_ptr<MockConnection> connection_;
159
167
172
176
179
182
183 private:
185 MultiDrivePolicy drive_policy_;
186
187 friend curl_socket_t MockServerBaseOpenSocketTrampoline(void*, curlsocktype, struct curl_sockaddr*);
188 friend int MockServerBaseSockOptTrampoline(void*, curl_socket_t, curlsocktype);
189};
190
191} // namespace proto_fuzzer
192
193#endif // PROTO_FUZZER_MOCK_SERVER_BASE_H_
Owns one half of a socketpair used to feed canned responses to libcurl.
Definition mock_server.h:29
Abstract base for protocol-specific in-process mock servers.
static bool UsesTimedDrive(const curl::fuzzer::proto::Scenario &scenario)
Treat a non-default BackpressureConfig as an explicit request for the slower, timed drive policy.
virtual void HandleDetachedMulti(CurlMultiPtr multi)
Dispose of or retain the multi after its easy handle has been removed.
virtual void RunLoop(CURLM *multi, CURL *easy, const curl::fuzzer::proto::Scenario &scenario)=0
Subclass hook invoked from DriveScenario.
virtual ConnectOnlyRunStats DriveConnectOnlyScenario(CURL *easy, const curl::fuzzer::proto::Scenario &scenario)
Establish a CONNECT_ONLY transport, then perform bounded direct I/O.
virtual void Install(CURL *easy)
Install the common OPENSOCKETFUNCTION / OPENSOCKETDATA / SOCKOPTFUNCTION callbacks on 'easy'.
CURLcode DriveScenario(CURL *easy, const curl::fuzzer::proto::Scenario &scenario)
Run 'scenario' to completion on 'easy': allocate a multi, attach 'easy', delegate protocol-specific w...
std::size_t additional_handle_cleanup_count() const
int pending_recv_buf_bytes_
Cached SO_RCVBUF/SO_SNDBUF setting in bytes.
std::unique_ptr< MockConnection > connection_
The per-scenario MockConnection, lazily created by HandleOpenSocket().
void SetMultiObserver(MultiObserver observer)
Register an observer invoked with the live multi handle after 'easy' is attached and before the drive...
std::size_t pending_drain_limit_
Cached per-call DrainIncoming byte budget.
static int WaitOnMultiFdset(CURLM *multi, CURLMcode *rc)
Wait on curl's fdset with a short timeout.
static constexpr int kMaxTimedIdleIterations
Explicit backpressure scenarios get a larger idle budget and may use the short timed wait above.
std::size_t additional_handle_cleanup_count_
Number of application-created handles, excluding the caller's parent, successfully removed from the c...
static void ProbeMultiPollset(CURLM *multi)
Ask curl to construct and inspect its connection-filter pollset without waiting.
friend curl_socket_t MockServerBaseOpenSocketTrampoline(void *, curlsocktype, struct curl_sockaddr *)
C trampoline for CURLOPT_OPENSOCKETFUNCTION.
virtual curl_socket_t HandleOpenSocket(curlsocktype purpose, struct curl_sockaddr *address)=0
Subclass hook invoked by the OPENSOCKET trampoline.
virtual void ObserveState()
Default no-op for peers without protocol-specific observations.
static constexpr int kMaxDriveIterations
Hard operation budget for one scenario.
bool resume_response_
True only for an API-plan multi drive with its one-shot write callback.
std::function< void(CURLM *)> MultiObserver
Callback type used to publish the driving multi handle to observers.
void ResumeResponseIfRequested(CURL *easy)
Resume receive-side callback output at one bounded drive boundary when the dedicated API plan request...
virtual SocketSetupDisposition GetSocketSetupDisposition(curl_socket_t curlfd, curlsocktype purpose) const
Describe the socket returned by HandleOpenSocket without issuing native descriptor queries.
MultiSocketDriver * multi_socket_driver_
Non-owning pointer into DriveScenario's stack.
static constexpr int kMaxIdleIterations
Consecutive no-progress budget for ordinary scenarios.
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 tak...
friend int MockServerBaseSockOptTrampoline(void *, curl_socket_t, curlsocktype)
Translate explicit peer transport metadata into curl's sockopt callback contract.
virtual void ConfigureRequestData(ScenarioRequestData *request_data)
Bind protocol-specific work to the request-data callbacks after their per-scenario state has been con...
MultiSocketDriver * multi_socket_driver()
Expose the callback state installed for the current socket-action drive.
virtual ~MockServerBase()
Out-of-line destructor so MockConnection can stay forward-declared in the base header (its complete t...
static bool MultiPollsetWantsWrite(CURLM *multi, curl_socket_t socket)
Inspect one socket's current writable interest through curl's public multi fdset API.
void ApplyPendingBackpressure()
Apply the BackpressureConfig cached by DriveScenario to the new connection_.
MultiObserver multi_observer_
Observer receiving the live multi handle at the start of a drive.
Owns the socket and timer callback state required by libcurl's event-driven multi API.
Builds HTTP headers or TELNET options, MIME state, and upload callbacks whose storage or userdata lib...
Common ownership types for independently cleaned-up curl handles.
std::unique_ptr< CURLM, CurlMultiDeleter > CurlMultiPtr
Unique ownership of a CURL multi handle.
Definition curl_raii.h:58
SocketSetupDisposition
Tell curl whether an application-provided socket still needs its normal connect/options setup or alre...
MultiDrivePolicy
Fixed policy for interpreting a scenario's multi-drive fields.
@ kFromApiPlan
Read the multi-loop choice and probes from Scenario::api_plan.
@ kPerform
Use the ordinary curl_multi_perform loop.
@ kSocketAction
Use the callback-driven curl_multi_socket_action loop.
Results from the bounded CONNECT_ONLY public-API probe.
CURLcode connect_result
Result of establishing the connect-only transport.
CURLcode recv_result
Final result returned by curl_easy_recv.
std::size_t received_bytes
Total application bytes returned by curl_easy_recv.
std::size_t sent_bytes
Total application bytes accepted by curl_easy_send.
CURLcode send_result
Final result returned by curl_easy_send.