19namespace proto_fuzzer {
28constexpr std::size_t kMinClientSendBufferBytes = 64 * 1024;
30static_assert(kMaxBufferedClientBytes < kMinClientSendBufferBytes,
31 "DICT mutation cap exceeds the verified client send buffer");
37class ScopedEnvironmentOverride {
39 ScopedEnvironmentOverride(
const char* name,
const char* value) : name_(name) {
40 const char* previous = std::getenv(name);
41 if (previous !=
nullptr) {
45 active_ = setenv(name, value, 1) == 0;
48 ~ScopedEnvironmentOverride() {
53 (void)setenv(name_.c_str(), previous_.c_str(), 1);
55 (void)unsetenv(name_.c_str());
59 ScopedEnvironmentOverride(
const ScopedEnvironmentOverride&) =
delete;
60 ScopedEnvironmentOverride& operator=(
const ScopedEnvironmentOverride&) =
delete;
64 std::string previous_;
65 bool had_previous_ =
false;
87 (void)curl_easy_setopt(easy, CURLOPT_TIMEOUT_MS, 0L);
98 !
connection->EnsureClientSendBufferSize(kMinClientSendBufferBytes)) {
113 ScopedEnvironmentOverride partial_writes(
"CURL_DBG_SOCK_WPARTIAL",
"50");
122 write_closed_ =
false;
126void DictMockServer::FinishResponse() {
130 write_closed_ =
true;
143 const std::string_view verb =
FirstToken(line);
170#if defined(PROTO_FUZZER_OBSERVE_STATE)
173 (void)dict_observation;
void Install(CURL *easy) override
Remove the operation deadline so a partial DICT request write exercises sendf()'s explicit no-timeout...
std::unique_ptr< MockConnection > CreateConnection() override
Construct the ordinary plaintext transport only when its client endpoint can queue the complete bound...
void HandleLine(std::string_view line) override
Answer the first lookup command in the request and ignore CLIENT, which is a bare identification line...
void RunLoop(CURLM *multi, CURL *easy, const curl::fuzzer::proto::Scenario &scenario) override
Split each sufficiently large socket write while curl constructs and uses this DICT connection.
void ObserveState() override
Retain protocol outcomes in coverage and introspector builds.
DictMockServer()
Begin without a borrowed protobuf or open socketpair.
~DictMockServer() override
Release the server-owned socketpair half after curl has returned its client descriptor.
void ResetProtocolState() override
Reset DICT's response bookkeeping for a new drive.
virtual void Install(CURL *easy)
Install the common OPENSOCKETFUNCTION / OPENSOCKETDATA / SOCKOPTFUNCTION callbacks on 'easy'.
std::unique_ptr< MockConnection > connection_
The per-scenario MockConnection, lazily created by HandleOpenSocket().
MockConnection * connection()
virtual void ObserveState()
Default no-op for peers without protocol-specific observations.
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 ...
const std::string & control_transcript() const
Expose the bounded command capture from the most recent drive so tests can verify protocol states wit...
bool WriteNextReply()
Consume the next scripted reply.
const curl::fuzzer::proto::Scenario * scenario() const
Borrowed scenario for the synchronous drive, or nullptr outside RunLoop().
virtual std::unique_ptr< MockConnection > CreateConnection()
Create the default plaintext transport.
static std::string_view FirstToken(std::string_view line)
Remove optional leading horizontal whitespace and return the first token without allocating.
const std::string & uploaded_data() const
Expose a bounded prefix of bytes drained during the most recent body phase while continuing to drain ...
static bool TokenEquals(std::string_view token, std::string_view expected_uppercase)
Fold only ASCII lowercase command letters.
Command-aware in-process peer for curl's DICT request/response.
MockConnection and MockServer — the in-process peer that feeds canned response bytes to libcurl over ...
Shared complexity limits for structured scenarios.
constexpr std::size_t kMaxDictHostPathBytes
DICT builds its complete command synchronously before the outer mock loop can drain curl's socket.