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

Unified Diff: remoting/jingle_glue/ssl_socket_adapter.cc

Issue 10543069: Fix SSLSocketAdapter to handle asynchronous writes appropriately. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 6 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 | « remoting/jingle_glue/ssl_socket_adapter.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: remoting/jingle_glue/ssl_socket_adapter.cc
diff --git a/remoting/jingle_glue/ssl_socket_adapter.cc b/remoting/jingle_glue/ssl_socket_adapter.cc
index b6b530dc5e367d45c54d90fb28ea8a9fe9097201..32afec09175284a5afa8f036fb773f9a8cef2b06 100644
--- a/remoting/jingle_glue/ssl_socket_adapter.cc
+++ b/remoting/jingle_glue/ssl_socket_adapter.cc
@@ -28,8 +28,9 @@ SSLSocketAdapter::SSLSocketAdapter(AsyncSocket* socket)
cert_verifier_(net::CertVerifier::CreateDefault()),
ssl_state_(SSLSTATE_NONE),
read_state_(IOSTATE_NONE),
- write_state_(IOSTATE_NONE),
- data_transferred_(0) {
+ read_buffer_size_(0),
+ read_buffer_position_(0),
+ write_state_(IOSTATE_NONE) {
transport_socket_ = new TransportSocket(socket, this);
}
@@ -83,20 +84,24 @@ int SSLSocketAdapter::BeginSSL() {
}
int SSLSocketAdapter::Send(const void* buf, size_t len) {
- if (ssl_state_ != SSLSTATE_CONNECTED) {
+ if (ssl_state_ == SSLSTATE_ERROR) {
+ SetError(EINVAL);
Wez 2012/06/11 21:21:35 You're avoiding just returning whatever error caus
Sergey Ulanov 2012/06/11 23:06:39 Correct. Send() returns one of the error codes def
+ return -1;
+ } else if (ssl_state_ != SSLSTATE_CONNECTED) {
Wez 2012/06/11 21:21:35 nit: Using "else" here makes this harder to read.
Sergey Ulanov 2012/06/11 23:06:39 Done.
return AsyncSocketAdapter::Send(buf, len);
Wez 2012/06/11 21:21:35 Add a comment to explain why we propagate the Send
Sergey Ulanov 2012/06/11 23:06:39 Done.
- } else {
- scoped_refptr<net::IOBuffer> transport_buf(new net::IOBuffer(len));
- memcpy(transport_buf->data(), buf, len);
+ }
- int result = ssl_socket_->Write(transport_buf, len,
- net::CompletionCallback());
- if (result == net::ERR_IO_PENDING) {
- SetError(EWOULDBLOCK);
- }
- transport_buf = NULL;
- return result;
+ if (write_state_ == IOSTATE_PENDING) {
+ SetError(EWOULDBLOCK);
+ return -1;
}
+
+ write_buffer_ = new net::DrainableIOBuffer(new net::IOBuffer(len), len);
+ memcpy(write_buffer_->data(), buf, len);
+
+ DoWrite();
+
+ return len;
}
int SSLSocketAdapter::Recv(void* buf, size_t len) {
@@ -111,12 +116,12 @@ int SSLSocketAdapter::Recv(void* buf, size_t len) {
case SSLSTATE_CONNECTED:
switch (read_state_) {
case IOSTATE_NONE: {
- transport_buf_ = new net::IOBuffer(len);
+ read_buffer_ = new net::IOBuffer(len);
int result = ssl_socket_->Read(
- transport_buf_, len,
+ read_buffer_, len,
base::Bind(&SSLSocketAdapter::OnRead, base::Unretained(this)));
if (result >= 0) {
- memcpy(buf, transport_buf_->data(), len);
+ memcpy(buf, read_buffer_->data(), len);
}
if (result == net::ERR_IO_PENDING) {
@@ -124,10 +129,11 @@ int SSLSocketAdapter::Recv(void* buf, size_t len) {
SetError(EWOULDBLOCK);
} else {
if (result < 0) {
- SetError(result);
- VLOG(1) << "Socket error " << result;
+ SetError(EINVAL);
+ ssl_state_ = SSLSTATE_ERROR;
+ LOG(ERROR) << "Error when reading from SSL socket " << result;
Wez 2012/06/11 21:21:35 nit: not need for "when" here
Sergey Ulanov 2012/06/11 23:06:39 Done.
}
- transport_buf_ = NULL;
+ read_buffer_ = NULL;
}
return result;
}
@@ -136,11 +142,20 @@ int SSLSocketAdapter::Recv(void* buf, size_t len) {
return -1;
case IOSTATE_COMPLETE:
- memcpy(buf, transport_buf_->data(), len);
- transport_buf_ = NULL;
- read_state_ = IOSTATE_NONE;
- return data_transferred_;
+ int size = std::min(read_buffer_size_ - read_buffer_position_,
+ static_cast<int>(len));
Wez 2012/06/11 21:21:35 You'll need {} in this case, since you're declarin
Wez 2012/06/11 21:21:35 nit: If len > read_buffer_size_ - read_buffer_posi
Sergey Ulanov 2012/06/11 23:06:39 Done.
+ memcpy(buf, read_buffer_->data() + read_buffer_position_, size);
+ read_buffer_position_ += size;
Wez 2012/06/11 21:21:35 Why use a buffer position rather than creating a D
Sergey Ulanov 2012/06/11 23:06:39 Drainable buffer doesn't allow truncating it. Repl
+ if (read_buffer_position_ == read_buffer_size_) {
+ read_buffer_ = NULL;
+ read_state_ = IOSTATE_NONE;
+ }
+ return size;
}
+
+ case SSLSTATE_ERROR:
+ SetError(EINVAL);
+ return -1;
}
NOTREACHED();
@@ -158,18 +173,51 @@ void SSLSocketAdapter::OnConnected(int result) {
void SSLSocketAdapter::OnRead(int result) {
DCHECK(read_state_ == IOSTATE_PENDING);
- read_state_ = IOSTATE_COMPLETE;
- data_transferred_ = result;
+ if (result > 0) {
+ read_state_ = IOSTATE_COMPLETE;
+ read_buffer_size_ = result;
+ read_buffer_position_ = 0;
+ } else {
+ read_state_ = IOSTATE_NONE;
+ if (result < 0) {
+ ssl_state_ = SSLSTATE_ERROR;
Wez 2012/06/11 21:21:35 nit: It's confusing that you have read_state_, wri
Sergey Ulanov 2012/06/11 23:06:39 Repalaced write_state_ and read_state_ with write_
+ }
+ }
AsyncSocketAdapter::OnReadEvent(this);
}
-void SSLSocketAdapter::OnWrite(int result) {
+void SSLSocketAdapter::OnWritten(int result) {
DCHECK(write_state_ == IOSTATE_PENDING);
write_state_ = IOSTATE_COMPLETE;
- data_transferred_ = result;
+ if (result >= 0) {
+ write_buffer_->DidConsume(result);
+ if (!write_buffer_->BytesRemaining()) {
+ write_buffer_ = NULL;
+ } else {
+ DoWrite();
+ }
+ } else {
+ ssl_state_ = SSLSTATE_ERROR;
+ }
AsyncSocketAdapter::OnWriteEvent(this);
}
+void SSLSocketAdapter::DoWrite() {
+ DCHECK_GT(write_buffer_->BytesRemaining(), 0);
Wez 2012/06/11 21:21:35 nit: DCHECK |write_state_| is not IO_PENDING?
Sergey Ulanov 2012/06/11 23:06:39 Done.
+ int result = ssl_socket_->Write(
+ write_buffer_, write_buffer_->BytesRemaining(),
+ base::Bind(&SSLSocketAdapter::OnWritten, base::Unretained(this)));
+
+ if (result == net::ERR_IO_PENDING) {
+ write_state_ = IOSTATE_PENDING;
+ } else if (result < 0) {
+ SetError(EINVAL);
+ ssl_state_ = SSLSTATE_ERROR;
+ } else {
+ write_buffer_ = NULL;
+ }
+}
+
void SSLSocketAdapter::OnConnectEvent(talk_base::AsyncSocket* socket) {
if (ssl_state_ != SSLSTATE_WAIT) {
AsyncSocketAdapter::OnConnectEvent(socket);
« no previous file with comments | « remoting/jingle_glue/ssl_socket_adapter.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698