• 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 #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