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