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 #include "net/socket/socket_bio_adapter.h"
6
7 #include <string.h>
8
9 #include <algorithm>
10
11 #include "base/check_op.h"
12 #include "base/functional/bind.h"
13 #include "base/location.h"
14 #include "base/notreached.h"
15 #include "base/task/single_thread_task_runner.h"
16 #include "net/base/io_buffer.h"
17 #include "net/base/net_errors.h"
18 #include "net/socket/socket.h"
19 #include "net/socket/stream_socket.h"
20 #include "net/ssl/openssl_ssl_util.h"
21 #include "net/traffic_annotation/network_traffic_annotation.h"
22 #include "third_party/boringssl/src/include/openssl/bio.h"
23
24 namespace {
25
26 const net::NetworkTrafficAnnotationTag kTrafficAnnotation =
27 net::DefineNetworkTrafficAnnotation("socket_bio_adapter", R"(
28 semantics {
29 sender: "Socket BIO Adapter"
30 description:
31 "SocketBIOAdapter is used only internal to //net code as an internal "
32 "detail to implement a TLS connection for a Socket class, and is not "
33 "being called directly outside of this abstraction."
34 trigger:
35 "Establishing a TLS connection to a remote endpoint. There are many "
36 "different ways in which a TLS connection may be triggered, such as "
37 "loading an HTTPS URL."
38 data:
39 "All data sent or received over a TLS connection. This traffic may "
40 "either be the handshake or application data. During the handshake, "
41 "the target host name, user's IP, data related to previous "
42 "handshake, client certificates, and channel ID, may be sent. When "
43 "the connection is used to load an HTTPS URL, the application data "
44 "includes cookies, request headers, and the response body."
45 destination: OTHER
46 destination_other:
47 "Any destination the implementing socket is connected to."
48 }
49 policy {
50 cookies_allowed: NO
51 setting: "This feature cannot be disabled."
52 policy_exception_justification: "Essential for navigation."
53 })");
54
55 } // namespace
56
57 namespace net {
58
SocketBIOAdapter(StreamSocket * socket,int read_buffer_capacity,int write_buffer_capacity,Delegate * delegate)59 SocketBIOAdapter::SocketBIOAdapter(StreamSocket* socket,
60 int read_buffer_capacity,
61 int write_buffer_capacity,
62 Delegate* delegate)
63 : socket_(socket),
64 read_buffer_capacity_(read_buffer_capacity),
65 write_buffer_capacity_(write_buffer_capacity),
66 delegate_(delegate) {
67 bio_.reset(BIO_new(&kBIOMethod));
68 bio_->ptr = this;
69 bio_->init = 1;
70
71 read_callback_ = base::BindRepeating(&SocketBIOAdapter::OnSocketReadComplete,
72 weak_factory_.GetWeakPtr());
73 write_callback_ = base::BindRepeating(
74 &SocketBIOAdapter::OnSocketWriteComplete, weak_factory_.GetWeakPtr());
75 }
76
77 SocketBIOAdapter::~SocketBIOAdapter() {
78 // BIOs are reference-counted and may outlive the adapter. Clear the pointer
79 // so future operations fail.
80 bio_->ptr = nullptr;
81 }
82
83 bool SocketBIOAdapter::HasPendingReadData() {
84 return read_result_ > 0;
85 }
86
87 size_t SocketBIOAdapter::GetAllocationSize() const {
88 size_t buffer_size = 0;
89 if (read_buffer_)
90 buffer_size += read_buffer_capacity_;
91
92 if (write_buffer_)
93 buffer_size += write_buffer_capacity_;
94 return buffer_size;
95 }
96
97 int SocketBIOAdapter::BIORead(char* out, int len) {
98 if (len <= 0)
99 return len;
100
101 // If there is no result available synchronously, report any Write() errors
102 // that were observed. Otherwise the application may have encountered a socket
103 // error while writing that would otherwise not be reported until the
104 // application attempted to write again - which it may never do. See
105 // https://crbug.com/249848.
106 if (write_error_ != OK && write_error_ != ERR_IO_PENDING &&
107 (read_result_ == 0 || read_result_ == ERR_IO_PENDING)) {
108 OpenSSLPutNetError(FROM_HERE, write_error_);
109 return -1;
110 }
111
112 if (read_result_ == 0) {
113 // Instantiate the read buffer and read from the socket. Although only |len|
114 // bytes were requested, intentionally read to the full buffer size. The SSL
115 // layer reads the record header and body in separate reads to avoid
116 // overreading, but issuing one is more efficient. SSL sockets are not
117 // reused after shutdown for non-SSL traffic, so overreading is fine.
118 DCHECK(!read_buffer_);
119 DCHECK_EQ(0, read_offset_);
120 read_buffer_ = base::MakeRefCounted<IOBuffer>(read_buffer_capacity_);
121 int result = socket_->ReadIfReady(
122 read_buffer_.get(), read_buffer_capacity_,
123 base::BindOnce(&SocketBIOAdapter::OnSocketReadIfReadyComplete,
124 weak_factory_.GetWeakPtr()));
125 if (result == ERR_IO_PENDING)
126 read_buffer_ = nullptr;
127 if (result == ERR_READ_IF_READY_NOT_IMPLEMENTED) {
128 result = socket_->Read(read_buffer_.get(), read_buffer_capacity_,
129 read_callback_);
130 }
131 if (result == ERR_IO_PENDING) {
132 read_result_ = ERR_IO_PENDING;
133 } else {
134 HandleSocketReadResult(result);
135 }
136 }
137
138 // There is a pending Read(). Inform the caller to retry when it completes.
139 if (read_result_ == ERR_IO_PENDING) {
140 BIO_set_retry_read(bio());
141 return -1;
142 }
143
144 // If the last Read() failed, report the error.
145 if (read_result_ < 0) {
146 OpenSSLPutNetError(FROM_HERE, read_result_);
147 return -1;
148 }
149
150 // Report the result of the last Read() if non-empty.
151 CHECK_LT(read_offset_, read_result_);
152 len = std::min(len, read_result_ - read_offset_);
153 memcpy(out, read_buffer_->data() + read_offset_, len);
154 read_offset_ += len;
155
156 // Release the buffer when empty.
157 if (read_offset_ == read_result_) {
158 read_buffer_ = nullptr;
159 read_offset_ = 0;
160 read_result_ = 0;
161 }
162
163 return len;
164 }
165
166 void SocketBIOAdapter::HandleSocketReadResult(int result) {
167 DCHECK_NE(ERR_IO_PENDING, result);
168
169 // If an EOF, canonicalize to ERR_CONNECTION_CLOSED here, so that higher
170 // levels don't report success.
171 if (result == 0)
172 result = ERR_CONNECTION_CLOSED;
173
174 read_result_ = result;
175
176 // The read buffer is no longer needed.
177 if (read_result_ <= 0)
178 read_buffer_ = nullptr;
179 }
180
181 void SocketBIOAdapter::OnSocketReadComplete(int result) {
182 DCHECK_EQ(ERR_IO_PENDING, read_result_);
183
184 HandleSocketReadResult(result);
185 delegate_->OnReadReady();
186 }
187
188 void SocketBIOAdapter::OnSocketReadIfReadyComplete(int result) {
189 DCHECK_EQ(ERR_IO_PENDING, read_result_);
190 DCHECK_GE(OK, result);
191
192 // Do not use HandleSocketReadResult() because result == OK doesn't mean EOF.
193 read_result_ = result;
194
195 delegate_->OnReadReady();
196 }
197
198 int SocketBIOAdapter::BIOWrite(const char* in, int len) {
199 if (len <= 0)
200 return len;
201
202 // If the write buffer is not empty, there must be a pending Write() to flush
203 // it.
204 DCHECK(write_buffer_used_ == 0 || write_error_ == ERR_IO_PENDING);
205
206 // If a previous Write() failed, report the error.
207 if (write_error_ != OK && write_error_ != ERR_IO_PENDING) {
208 OpenSSLPutNetError(FROM_HERE, write_error_);
209 return -1;
210 }
211
212 // Instantiate the write buffer if needed.
213 if (!write_buffer_) {
214 DCHECK_EQ(0, write_buffer_used_);
215 write_buffer_ = base::MakeRefCounted<GrowableIOBuffer>();
216 write_buffer_->SetCapacity(write_buffer_capacity_);
217 }
218
219 // If the ring buffer is full, inform the caller to try again later.
220 if (write_buffer_used_ == write_buffer_->capacity()) {
221 BIO_set_retry_write(bio());
222 return -1;
223 }
224
225 int bytes_copied = 0;
226
227 // If there is space after the offset, fill it.
228 if (write_buffer_used_ < write_buffer_->RemainingCapacity()) {
229 int chunk =
230 std::min(write_buffer_->RemainingCapacity() - write_buffer_used_, len);
231 memcpy(write_buffer_->data() + write_buffer_used_, in, chunk);
232 in += chunk;
233 len -= chunk;
234 bytes_copied += chunk;
235 write_buffer_used_ += chunk;
236 }
237
238 // If there is still space for remaining data, try to wrap around.
239 if (len > 0 && write_buffer_used_ < write_buffer_->capacity()) {
240 // If there were any room after the offset, the previous branch would have
241 // filled it.
242 CHECK_LE(write_buffer_->RemainingCapacity(), write_buffer_used_);
243 int write_offset = write_buffer_used_ - write_buffer_->RemainingCapacity();
244 int chunk = std::min(len, write_buffer_->capacity() - write_buffer_used_);
245 memcpy(write_buffer_->StartOfBuffer() + write_offset, in, chunk);
246 in += chunk;
247 len -= chunk;
248 bytes_copied += chunk;
249 write_buffer_used_ += chunk;
250 }
251
252 // Either the buffer is now full or there is no more input.
253 DCHECK(len == 0 || write_buffer_used_ == write_buffer_->capacity());
254
255 // Schedule a socket Write() if necessary. (The ring buffer may previously
256 // have been empty.)
257 SocketWrite();
258
259 // If a read-interrupting write error was synchronously discovered,
260 // asynchronously notify OnReadReady. See https://crbug.com/249848. Avoid
261 // reentrancy by deferring it to a later event loop iteration.
262 if (write_error_ != OK && write_error_ != ERR_IO_PENDING &&
263 read_result_ == ERR_IO_PENDING) {
264 base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
265 FROM_HERE, base::BindOnce(&SocketBIOAdapter::CallOnReadReady,
266 weak_factory_.GetWeakPtr()));
267 }
268
269 return bytes_copied;
270 }
271
272 void SocketBIOAdapter::SocketWrite() {
273 while (write_error_ == OK && write_buffer_used_ > 0) {
274 int write_size =
275 std::min(write_buffer_used_, write_buffer_->RemainingCapacity());
276 int result = socket_->Write(write_buffer_.get(), write_size,
277 write_callback_, kTrafficAnnotation);
278 if (result == ERR_IO_PENDING) {
279 write_error_ = ERR_IO_PENDING;
280 return;
281 }
282
283 HandleSocketWriteResult(result);
284 }
285 }
286
287 void SocketBIOAdapter::HandleSocketWriteResult(int result) {
288 DCHECK_NE(ERR_IO_PENDING, result);
289
290 if (result < 0) {
291 write_error_ = result;
292
293 // The write buffer is no longer needed.
294 write_buffer_ = nullptr;
295 write_buffer_used_ = 0;
296 return;
297 }
298
299 // Advance the ring buffer.
300 write_buffer_->set_offset(write_buffer_->offset() + result);
301 write_buffer_used_ -= result;
302 if (write_buffer_->RemainingCapacity() == 0)
303 write_buffer_->set_offset(0);
304 write_error_ = OK;
305
306 // Release the write buffer if empty.
307 if (write_buffer_used_ == 0)
308 write_buffer_ = nullptr;
309 }
310
311 void SocketBIOAdapter::OnSocketWriteComplete(int result) {
312 DCHECK_EQ(ERR_IO_PENDING, write_error_);
313
314 bool was_full = write_buffer_used_ == write_buffer_->capacity();
315
316 HandleSocketWriteResult(result);
317 SocketWrite();
318
319 // If transitioning from being unable to accept data to being able to, signal
320 // OnWriteReady.
321 if (was_full) {
322 base::WeakPtr<SocketBIOAdapter> guard(weak_factory_.GetWeakPtr());
323 delegate_->OnWriteReady();
324 // OnWriteReady may delete the adapter.
325 if (!guard)
326 return;
327 }
328
329 // Write errors are fed back into BIO_read once the read buffer is empty. If
330 // BIO_read is currently blocked, signal early that a read result is ready.
331 if (result < 0 && read_result_ == ERR_IO_PENDING)
332 delegate_->OnReadReady();
333 }
334
335 void SocketBIOAdapter::CallOnReadReady() {
336 if (read_result_ == ERR_IO_PENDING)
337 delegate_->OnReadReady();
338 }
339
340 SocketBIOAdapter* SocketBIOAdapter::GetAdapter(BIO* bio) {
341 DCHECK_EQ(&kBIOMethod, bio->method);
342 SocketBIOAdapter* adapter = reinterpret_cast<SocketBIOAdapter*>(bio->ptr);
343 if (adapter)
344 DCHECK_EQ(bio, adapter->bio());
345 return adapter;
346 }
347
348 int SocketBIOAdapter::BIOWriteWrapper(BIO* bio, const char* in, int len) {
349 BIO_clear_retry_flags(bio);
350
351 SocketBIOAdapter* adapter = GetAdapter(bio);
352 if (!adapter) {
353 OpenSSLPutNetError(FROM_HERE, ERR_UNEXPECTED);
354 return -1;
355 }
356
357 return adapter->BIOWrite(in, len);
358 }
359
360 int SocketBIOAdapter::BIOReadWrapper(BIO* bio, char* out, int len) {
361 BIO_clear_retry_flags(bio);
362
363 SocketBIOAdapter* adapter = GetAdapter(bio);
364 if (!adapter) {
365 OpenSSLPutNetError(FROM_HERE, ERR_UNEXPECTED);
366 return -1;
367 }
368
369 return adapter->BIORead(out, len);
370 }
371
372 long SocketBIOAdapter::BIOCtrlWrapper(BIO* bio,
373 int cmd,
374 long larg,
375 void* parg) {
376 switch (cmd) {
377 case BIO_CTRL_FLUSH:
378 // The SSL stack requires BIOs handle BIO_flush.
379 return 1;
380 }
381
382 NOTIMPLEMENTED();
383 return 0;
384 }
385
386 const BIO_METHOD SocketBIOAdapter::kBIOMethod = {
387 0, // type (unused)
388 nullptr, // name (unused)
389 SocketBIOAdapter::BIOWriteWrapper,
390 SocketBIOAdapter::BIOReadWrapper,
391 nullptr, // puts
392 nullptr, // gets
393 SocketBIOAdapter::BIOCtrlWrapper,
394 nullptr, // create
395 nullptr, // destroy
396 nullptr, // callback_ctrl
397 };
398
399 } // namespace net
400