Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1194)

Unified Diff: net/socket/ssl_client_socket_openssl.cc

Issue 255143002: Implement zero-copy SSL buffers. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/socket/ssl_client_socket_openssl.cc
diff --git a/net/socket/ssl_client_socket_openssl.cc b/net/socket/ssl_client_socket_openssl.cc
index d6345f71501d2acc3e20384943045d90ebdfa846..f30715d3577088092683bb0025724c7d2fc71a03 100644
--- a/net/socket/ssl_client_socket_openssl.cc
+++ b/net/socket/ssl_client_socket_openssl.cc
@@ -1277,10 +1277,22 @@ int SSLClientSocketOpenSSL::BufferSend(void) {
size_t max_read = BIO_ctrl_pending(transport_bio_);
if (!max_read)
return 0; // Nothing pending in the OpenSSL write BIO.
- send_buffer_ = new DrainableIOBuffer(new IOBuffer(max_read), max_read);
- int read_bytes = BIO_read(transport_bio_, send_buffer_->data(), max_read);
- DCHECK_GT(read_bytes, 0);
- CHECK_EQ(static_cast<int>(max_read), read_bytes);
+
+ char* bio_transport_buf;
+ // Get the internal buffer and number of bytes available for non-copying
+ // read.
+ // BIO_ctrl_pending() is still called above. Calling BIO_nread0() when
+ // there is no data triggers a call to BIO_nread() to read one byte. This
+ // has side effect that the retry flag is set.
+ int available_read_bytes = BIO_nread0(transport_bio_, &bio_transport_buf);
Ryan Sleevi 2014/04/29 18:57:02 Note the comments in bss_bio.c WARNING: The non-c
haavardm 2014/04/29 20:52:56 Yes I saw that too and agree it's a bit risky, esp
+ // BIO_nread0() might report less than BIO_ctrl_pending() due to the buffer
+ // offset and no ring buffer wrap-around for non-copying interface.
+ CHECK_GE(static_cast<int>(max_read), available_read_bytes);
Ryan Sleevi 2014/04/29 18:57:02 Two things: 1) I'm a little nervous about this CHE
haavardm 2014/04/29 20:52:56 Normally, if the read/write index is in the middle
+ if (available_read_bytes <= 0)
+ return 0;
+
+ send_buffer_ = new DrainableIOBuffer(new WrappedIOBuffer(bio_transport_buf),
+ available_read_bytes);
Ryan Sleevi 2014/04/29 18:57:02 BUG: So, the contract of IOBuffer is that, althoug
haavardm 2014/04/29 20:52:56 Ah, right. I knew about the contract for IOBuffer
}
int rv = transport_->socket()->Write(
@@ -1322,10 +1334,20 @@ int SSLClientSocketOpenSSL::BufferRecv(void) {
if (!max_write)
return ERR_IO_PENDING;
- recv_buffer_ = new IOBuffer(max_write);
+ char* bio_transport_buf;
+ // Get the internal buffer and number of bytes available for non-copying
+ // write.
+ int available_write_bytes = BIO_nwrite0(transport_bio_, &bio_transport_buf);
+ // BIO_nwrite0() might report less than BIO_ctrl_get_write_guarantee() due to
+ // the buffer offset and no ring buffer wrap-around for non-copying interface.
+ DCHECK_GE(static_cast<int>(max_write), available_write_bytes);
+ if (available_write_bytes <= 0)
+ return ERR_IO_PENDING;
+
+ recv_buffer_ = new WrappedIOBuffer(bio_transport_buf);
int rv = transport_->socket()->Read(
recv_buffer_.get(),
- max_write,
+ available_write_bytes,
base::Bind(&SSLClientSocketOpenSSL::BufferRecvComplete,
base::Unretained(this)));
if (rv == ERR_IO_PENDING) {
@@ -1367,6 +1389,11 @@ void SSLClientSocketOpenSSL::TransportWriteComplete(int result) {
send_buffer_ = NULL;
} else {
DCHECK(send_buffer_.get());
+ char* bio_transport_buf;
+ // Advance the buffer index.
+ int ret = BIO_nread(transport_bio_, &bio_transport_buf, result);
+ CHECK_EQ(ret, result);
+ CHECK_EQ(bio_transport_buf, send_buffer_->data());
send_buffer_->DidConsume(result);
DCHECK_GE(send_buffer_->BytesRemaining(), 0);
if (send_buffer_->BytesRemaining() <= 0)
@@ -1390,8 +1417,11 @@ int SSLClientSocketOpenSSL::TransportReadComplete(int result) {
// the CHECK. http://crbug.com/335557.
result = transport_write_error_;
} else {
- DCHECK(recv_buffer_.get());
- int ret = BIO_write(transport_bio_, recv_buffer_->data(), result);
+ char* bio_transport_buf;
+ // Set the amount of data read into buffer.
+ int ret = BIO_nwrite(transport_bio_, &bio_transport_buf, result);
+ CHECK_EQ(ret, result);
+ CHECK_EQ(bio_transport_buf, recv_buffer_->data());
// A write into a memory BIO should always succeed.
// Force values on the stack for http://crbug.com/335557
base::debug::Alias(&result);
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698