Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 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_SOCKET_BIO_ADAPTER_H_ | |
| 6 #define NET_SOCKET_SOCKET_BIO_ADAPTER_H_ | |
| 7 | |
| 8 #include <openssl/base.h> | |
| 9 | |
| 10 #include "base/memory/ref_counted.h" | |
| 11 #include "base/memory/weak_ptr.h" | |
| 12 #include "net/base/completion_callback.h" | |
| 13 #include "net/base/net_export.h" | |
| 14 | |
| 15 namespace net { | |
| 16 | |
| 17 class GrowableIOBuffer; | |
| 18 class IOBuffer; | |
| 19 class StreamSocket; | |
| 20 | |
| 21 // An adapter to convert between StreamSocket and OpenSSL BIO I/O models. | |
| 22 // | |
| 23 // BIO exposes a UNIX-like interface where BIO_read and BIO_write may either | |
| 24 // succeed synchronously or be retried (with no memory between calls). | |
| 25 // StreamSocket exposes an asynchronous interface where an asynchronous | |
| 26 // operation continues running and completes with a callback. | |
| 27 // | |
| 28 // For reading, SocketBIOAdapter maintains a buffer to pass to | |
| 29 // StreamSocket::Read. Once that Read completes, BIO_read synchronously drains | |
| 30 // the buffer and signals BIO_should_read once empty. | |
| 31 // | |
| 32 // For writing, SocketBIOAdapter maintains a ring buffer of data to be written | |
| 33 // to the StreamSocket. BIO_write synchronously copies data into the buffer or | |
| 34 // signals BIO_should_write if the buffer is full. The ring buffer is drained | |
| 35 // asynchronously into the socket. Note this means write errors are reported at | |
| 36 // a later BIO_write. | |
| 37 // | |
| 38 // To work around this delay, write errors are also surfaced out of | |
| 39 // BIO_read. Otherwise a failure in the final BIO_write of an application may go | |
| 40 // unnoticed. If this occurs, OnReadReady will be signaled as if it were a read | |
| 41 // error. See https://crbug.com/249848. | |
| 42 class NET_EXPORT_PRIVATE SocketBIOAdapter { | |
| 43 public: | |
| 44 // A delegate interface for when the sockets are ready. BIO assumes external | |
| 45 // knowledge of when to retry operations (such as a select() loop for UNIX), | |
| 46 // which is signaled out of StreamSocket's callbacks here. | |
| 47 // | |
| 48 // Callers should implement these methods and, when signaled, retry the | |
| 49 // BIO_read or BIO_write. This usually is done by retrying a higher-level | |
| 50 // operation, such as SSL_read or SSL_write. | |
| 51 // | |
| 52 // Callers may assume that OnReadReady and OnWriteReady will only be called | |
| 53 // from a PostTask or StreamSocket callback. | |
| 54 class Delegate { | |
|
Ryan Sleevi
2016/10/18 01:30:17
nit: Add protected virtual dtor, since you don't r
davidben
2016/10/18 20:49:11
Done.
| |
| 55 public: | |
| 56 // Called when the BIO is ready to handle BIO_read, after having previously | |
| 57 // been blocked. | |
| 58 virtual void OnReadReady() = 0; | |
| 59 | |
| 60 // Called when the BIO is ready to handle BIO_write, after having previously | |
| 61 // been blocked. | |
| 62 virtual void OnWriteReady() = 0; | |
| 63 }; | |
| 64 | |
| 65 // Creates a new SocketBIOAdapter for the specified socket. |socket| and | |
| 66 // |delegate| must remain valid for the lifetime of the SocketBIOAdapter. | |
| 67 SocketBIOAdapter(StreamSocket* socket, | |
| 68 int read_buffer_capacity, | |
| 69 int write_buffer_capacity, | |
| 70 Delegate* delegate); | |
| 71 ~SocketBIOAdapter(); | |
| 72 | |
| 73 BIO* bio() { return bio_.get(); } | |
| 74 | |
| 75 // Returns true if any data has been read from the underlying StreamSocket, | |
| 76 // but not yet consumed by the BIO. | |
| 77 bool HasPendingReadData(); | |
| 78 | |
| 79 private: | |
| 80 int BIORead(char* out, int len); | |
| 81 void HandleSocketReadResult(int result); | |
| 82 void OnSocketReadComplete(int result); | |
| 83 | |
| 84 int BIOWrite(const char* in, int len); | |
| 85 void SocketWrite(); | |
| 86 void HandleSocketWriteResult(int result); | |
| 87 void OnSocketWriteComplete(int result); | |
| 88 void CallOnReadReady(); | |
| 89 | |
| 90 static SocketBIOAdapter* GetAdapter(BIO* bio); | |
| 91 static int BIOReadWrapper(BIO* bio, char* out, int len); | |
| 92 static int BIOWriteWrapper(BIO* bio, const char* in, int len); | |
| 93 static long BIOCtrlWrapper(BIO* bio, int cmd, long larg, void* parg); | |
| 94 | |
| 95 static const BIO_METHOD kBIOMethod; | |
| 96 | |
| 97 bssl::UniquePtr<BIO> bio_; | |
| 98 | |
| 99 // The pointer is non-owning so this class may be used with both | |
| 100 // ClientSocketHandles and raw StreamSockets. | |
| 101 StreamSocket* socket_; | |
| 102 | |
| 103 CompletionCallback read_callback_; | |
| 104 CompletionCallback write_callback_; | |
| 105 | |
| 106 // The capacity of the read buffer. | |
| 107 int read_buffer_capacity_; | |
| 108 // A buffer containing data from the most recent socket Read(). The buffer is | |
| 109 // deallocated when unused. | |
| 110 scoped_refptr<IOBuffer> read_buffer_; | |
| 111 // The number of bytes of read_buffer_ consumed. | |
| 112 int read_offset_; | |
| 113 // The result of the most recent socket Read(). If ERR_IO_PENDING, there is a | |
| 114 // socket Read() in progress. If another error, Read() has failed. Otherwise, | |
| 115 // it is the number of bytes in the buffer (zero if empty). | |
| 116 int read_result_; | |
| 117 | |
| 118 // The capacity of the write buffer. | |
| 119 int write_buffer_capacity_; | |
| 120 // A ring buffer of data to be written to the transport. The offset of the | |
| 121 // buffer is the start of the ring buffer and is advanced on successful | |
| 122 // Write(). The buffer is deallocated when unused. | |
| 123 scoped_refptr<GrowableIOBuffer> write_buffer_; | |
| 124 // The number of bytes of data in write_buffer_. | |
| 125 int write_buffer_used_; | |
| 126 // The most recent socket Write() error. If ERR_IO_PENDING, there is a socket | |
| 127 // Write() in progress. If OK, there is no socket Write() in progress and none | |
| 128 // have failed. | |
| 129 int write_error_; | |
| 130 | |
| 131 Delegate* delegate_; | |
| 132 | |
| 133 base::WeakPtrFactory<SocketBIOAdapter> weak_factory_; | |
| 134 | |
| 135 DISALLOW_COPY_AND_ASSIGN(SocketBIOAdapter); | |
| 136 }; | |
| 137 | |
| 138 } // namespace net | |
| 139 | |
| 140 #endif // NET_SOCKET_SOCKET_BIO_ADAPTER_H_ | |
| OLD | NEW |