xref: /aosp_15_r20/external/cronet/net/socket/fuzzed_socket.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2016 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #ifndef NET_SOCKET_FUZZED_SOCKET_H_
6*6777b538SAndroid Build Coastguard Worker #define NET_SOCKET_FUZZED_SOCKET_H_
7*6777b538SAndroid Build Coastguard Worker 
8*6777b538SAndroid Build Coastguard Worker #include <stdint.h>
9*6777b538SAndroid Build Coastguard Worker 
10*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h"
11*6777b538SAndroid Build Coastguard Worker #include "base/memory/weak_ptr.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_piece.h"
13*6777b538SAndroid Build Coastguard Worker #include "net/base/completion_once_callback.h"
14*6777b538SAndroid Build Coastguard Worker #include "net/base/ip_endpoint.h"
15*6777b538SAndroid Build Coastguard Worker #include "net/base/net_errors.h"
16*6777b538SAndroid Build Coastguard Worker #include "net/log/net_log_with_source.h"
17*6777b538SAndroid Build Coastguard Worker #include "net/socket/transport_client_socket.h"
18*6777b538SAndroid Build Coastguard Worker #include "net/traffic_annotation/network_traffic_annotation.h"
19*6777b538SAndroid Build Coastguard Worker 
20*6777b538SAndroid Build Coastguard Worker class FuzzedDataProvider;
21*6777b538SAndroid Build Coastguard Worker 
22*6777b538SAndroid Build Coastguard Worker namespace net {
23*6777b538SAndroid Build Coastguard Worker 
24*6777b538SAndroid Build Coastguard Worker class IPEndPoint;
25*6777b538SAndroid Build Coastguard Worker class IOBuffer;
26*6777b538SAndroid Build Coastguard Worker class NetLog;
27*6777b538SAndroid Build Coastguard Worker 
28*6777b538SAndroid Build Coastguard Worker // A StreamSocket that uses a FuzzedDataProvider to generate responses. Writes
29*6777b538SAndroid Build Coastguard Worker // can succeed synchronously or asynchronously, can write some or all of the
30*6777b538SAndroid Build Coastguard Worker // provided data, and can fail with several different errors. Reads can do the
31*6777b538SAndroid Build Coastguard Worker // same, but the read data is also generated from the FuzzedDataProvider. The
32*6777b538SAndroid Build Coastguard Worker // number of bytes written/read from a single call is currently capped at 255
33*6777b538SAndroid Build Coastguard Worker // bytes.
34*6777b538SAndroid Build Coastguard Worker //
35*6777b538SAndroid Build Coastguard Worker // Reads and writes are executed independently of one another, so to guarantee
36*6777b538SAndroid Build Coastguard Worker // the fuzzer behaves the same across repeated runs with the same input, the
37*6777b538SAndroid Build Coastguard Worker // reads and writes must be done in a deterministic order and for a
38*6777b538SAndroid Build Coastguard Worker // deterministic number of bytes, every time the fuzzer is run with the same
39*6777b538SAndroid Build Coastguard Worker // data.
40*6777b538SAndroid Build Coastguard Worker class FuzzedSocket : public TransportClientSocket {
41*6777b538SAndroid Build Coastguard Worker  public:
42*6777b538SAndroid Build Coastguard Worker   // |data_provider| is used as to determine behavior of the FuzzedSocket. It
43*6777b538SAndroid Build Coastguard Worker   // must remain valid until after the FuzzedSocket is destroyed.
44*6777b538SAndroid Build Coastguard Worker   FuzzedSocket(FuzzedDataProvider* data_provider, net::NetLog* net_log);
45*6777b538SAndroid Build Coastguard Worker 
46*6777b538SAndroid Build Coastguard Worker   FuzzedSocket(const FuzzedSocket&) = delete;
47*6777b538SAndroid Build Coastguard Worker   FuzzedSocket& operator=(const FuzzedSocket&) = delete;
48*6777b538SAndroid Build Coastguard Worker 
49*6777b538SAndroid Build Coastguard Worker   ~FuzzedSocket() override;
50*6777b538SAndroid Build Coastguard Worker 
51*6777b538SAndroid Build Coastguard Worker   // If set to true, the socket will fuzz the result of the Connect() call.
52*6777b538SAndroid Build Coastguard Worker   // It can fail or succeed, and return synchronously or asynchronously. If
53*6777b538SAndroid Build Coastguard Worker   // false, Connect() succeeds synchronously. Defaults to false.
set_fuzz_connect_result(bool fuzz_connect_result)54*6777b538SAndroid Build Coastguard Worker   void set_fuzz_connect_result(bool fuzz_connect_result) {
55*6777b538SAndroid Build Coastguard Worker     fuzz_connect_result_ = fuzz_connect_result;
56*6777b538SAndroid Build Coastguard Worker   }
57*6777b538SAndroid Build Coastguard Worker 
58*6777b538SAndroid Build Coastguard Worker   // Sets the remote address the socket claims to be using.
set_remote_address(const IPEndPoint & remote_address)59*6777b538SAndroid Build Coastguard Worker   void set_remote_address(const IPEndPoint& remote_address) {
60*6777b538SAndroid Build Coastguard Worker     remote_address_ = remote_address;
61*6777b538SAndroid Build Coastguard Worker   }
62*6777b538SAndroid Build Coastguard Worker 
63*6777b538SAndroid Build Coastguard Worker   // Socket implementation:
64*6777b538SAndroid Build Coastguard Worker   int Read(IOBuffer* buf,
65*6777b538SAndroid Build Coastguard Worker            int buf_len,
66*6777b538SAndroid Build Coastguard Worker            CompletionOnceCallback callback) override;
67*6777b538SAndroid Build Coastguard Worker   int Write(IOBuffer* buf,
68*6777b538SAndroid Build Coastguard Worker             int buf_len,
69*6777b538SAndroid Build Coastguard Worker             CompletionOnceCallback callback,
70*6777b538SAndroid Build Coastguard Worker             const NetworkTrafficAnnotationTag& traffic_annotation) override;
71*6777b538SAndroid Build Coastguard Worker   int SetReceiveBufferSize(int32_t size) override;
72*6777b538SAndroid Build Coastguard Worker   int SetSendBufferSize(int32_t size) override;
73*6777b538SAndroid Build Coastguard Worker 
74*6777b538SAndroid Build Coastguard Worker   // TransportClientSocket implementation:
75*6777b538SAndroid Build Coastguard Worker   int Bind(const net::IPEndPoint& local_addr) override;
76*6777b538SAndroid Build Coastguard Worker   // StreamSocket implementation:
77*6777b538SAndroid Build Coastguard Worker   int Connect(CompletionOnceCallback callback) override;
78*6777b538SAndroid Build Coastguard Worker   void Disconnect() override;
79*6777b538SAndroid Build Coastguard Worker   bool IsConnected() const override;
80*6777b538SAndroid Build Coastguard Worker   bool IsConnectedAndIdle() const override;
81*6777b538SAndroid Build Coastguard Worker   int GetPeerAddress(IPEndPoint* address) const override;
82*6777b538SAndroid Build Coastguard Worker   int GetLocalAddress(IPEndPoint* address) const override;
83*6777b538SAndroid Build Coastguard Worker   const NetLogWithSource& NetLog() const override;
84*6777b538SAndroid Build Coastguard Worker   bool WasEverUsed() const override;
85*6777b538SAndroid Build Coastguard Worker   NextProto GetNegotiatedProtocol() const override;
86*6777b538SAndroid Build Coastguard Worker   bool GetSSLInfo(SSLInfo* ssl_info) override;
87*6777b538SAndroid Build Coastguard Worker   int64_t GetTotalReceivedBytes() const override;
88*6777b538SAndroid Build Coastguard Worker   void ApplySocketTag(const net::SocketTag& tag) override;
89*6777b538SAndroid Build Coastguard Worker 
90*6777b538SAndroid Build Coastguard Worker  private:
91*6777b538SAndroid Build Coastguard Worker   // Returns a net::Error that can be returned by a read or a write. Reads and
92*6777b538SAndroid Build Coastguard Worker   // writes return basically the same set of errors, at the TCP socket layer.
93*6777b538SAndroid Build Coastguard Worker   Error ConsumeReadWriteErrorFromData();
94*6777b538SAndroid Build Coastguard Worker 
95*6777b538SAndroid Build Coastguard Worker   void OnReadComplete(CompletionOnceCallback callback, int result);
96*6777b538SAndroid Build Coastguard Worker   void OnWriteComplete(CompletionOnceCallback callback, int result);
97*6777b538SAndroid Build Coastguard Worker   void OnConnectComplete(CompletionOnceCallback callback, int result);
98*6777b538SAndroid Build Coastguard Worker 
99*6777b538SAndroid Build Coastguard Worker   // Returns whether all operations should be synchronous.  Starts returning
100*6777b538SAndroid Build Coastguard Worker   // true once there have been too many async reads and writes, as spinning the
101*6777b538SAndroid Build Coastguard Worker   // message loop too often tends to cause fuzzers to time out.
102*6777b538SAndroid Build Coastguard Worker   // See https://crbug.com/823012
103*6777b538SAndroid Build Coastguard Worker   bool ForceSync() const;
104*6777b538SAndroid Build Coastguard Worker 
105*6777b538SAndroid Build Coastguard Worker   raw_ptr<FuzzedDataProvider> data_provider_;
106*6777b538SAndroid Build Coastguard Worker 
107*6777b538SAndroid Build Coastguard Worker   // If true, the result of the Connect() call is fuzzed - it can succeed or
108*6777b538SAndroid Build Coastguard Worker   // fail with a variety of connection errors, and it can complete synchronously
109*6777b538SAndroid Build Coastguard Worker   // or asynchronously.
110*6777b538SAndroid Build Coastguard Worker   bool fuzz_connect_result_ = false;
111*6777b538SAndroid Build Coastguard Worker 
112*6777b538SAndroid Build Coastguard Worker   bool connect_pending_ = false;
113*6777b538SAndroid Build Coastguard Worker   bool read_pending_ = false;
114*6777b538SAndroid Build Coastguard Worker   bool write_pending_ = false;
115*6777b538SAndroid Build Coastguard Worker 
116*6777b538SAndroid Build Coastguard Worker   // This is true when the first callback returning an error is pending in the
117*6777b538SAndroid Build Coastguard Worker   // message queue. If true, the socket acts like it's connected until that task
118*6777b538SAndroid Build Coastguard Worker   // is run (Or Disconnect() is called), and reads / writes will return the same
119*6777b538SAndroid Build Coastguard Worker   // error asynchronously, until it becomes false, at which point they'll return
120*6777b538SAndroid Build Coastguard Worker   // it synchronously.
121*6777b538SAndroid Build Coastguard Worker   bool error_pending_ = false;
122*6777b538SAndroid Build Coastguard Worker   // If this is not OK, all reads/writes will fail with this error.
123*6777b538SAndroid Build Coastguard Worker   int net_error_ = ERR_CONNECTION_CLOSED;
124*6777b538SAndroid Build Coastguard Worker 
125*6777b538SAndroid Build Coastguard Worker   int64_t total_bytes_read_ = 0;
126*6777b538SAndroid Build Coastguard Worker   int64_t total_bytes_written_ = 0;
127*6777b538SAndroid Build Coastguard Worker 
128*6777b538SAndroid Build Coastguard Worker   int num_async_reads_and_writes_ = 0;
129*6777b538SAndroid Build Coastguard Worker 
130*6777b538SAndroid Build Coastguard Worker   NetLogWithSource net_log_;
131*6777b538SAndroid Build Coastguard Worker 
132*6777b538SAndroid Build Coastguard Worker   IPEndPoint remote_address_;
133*6777b538SAndroid Build Coastguard Worker 
134*6777b538SAndroid Build Coastguard Worker   base::WeakPtrFactory<FuzzedSocket> weak_factory_{this};
135*6777b538SAndroid Build Coastguard Worker };
136*6777b538SAndroid Build Coastguard Worker 
137*6777b538SAndroid Build Coastguard Worker }  // namespace net
138*6777b538SAndroid Build Coastguard Worker 
139*6777b538SAndroid Build Coastguard Worker #endif  // NET_SOCKET_FUZZED_SOCKET_H_
140