Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "remoting/jingle_glue/ssl_socket_adapter.h" | 5 #include "remoting/jingle_glue/ssl_socket_adapter.h" |
| 6 | 6 |
| 7 #include "base/base64.h" | 7 #include "base/base64.h" |
| 8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
| 9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
| 10 #include "jingle/glue/utils.h" | 10 #include "jingle/glue/utils.h" |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 21 SSLSocketAdapter* SSLSocketAdapter::Create(AsyncSocket* socket) { | 21 SSLSocketAdapter* SSLSocketAdapter::Create(AsyncSocket* socket) { |
| 22 return new SSLSocketAdapter(socket); | 22 return new SSLSocketAdapter(socket); |
| 23 } | 23 } |
| 24 | 24 |
| 25 SSLSocketAdapter::SSLSocketAdapter(AsyncSocket* socket) | 25 SSLSocketAdapter::SSLSocketAdapter(AsyncSocket* socket) |
| 26 : SSLAdapter(socket), | 26 : SSLAdapter(socket), |
| 27 ignore_bad_cert_(false), | 27 ignore_bad_cert_(false), |
| 28 cert_verifier_(net::CertVerifier::CreateDefault()), | 28 cert_verifier_(net::CertVerifier::CreateDefault()), |
| 29 ssl_state_(SSLSTATE_NONE), | 29 ssl_state_(SSLSTATE_NONE), |
| 30 read_state_(IOSTATE_NONE), | 30 read_state_(IOSTATE_NONE), |
| 31 write_state_(IOSTATE_NONE), | 31 read_buffer_size_(0), |
| 32 data_transferred_(0) { | 32 read_buffer_position_(0), |
| 33 write_state_(IOSTATE_NONE) { | |
| 33 transport_socket_ = new TransportSocket(socket, this); | 34 transport_socket_ = new TransportSocket(socket, this); |
| 34 } | 35 } |
| 35 | 36 |
| 36 SSLSocketAdapter::~SSLSocketAdapter() { | 37 SSLSocketAdapter::~SSLSocketAdapter() { |
| 37 } | 38 } |
| 38 | 39 |
| 39 int SSLSocketAdapter::StartSSL(const char* hostname, bool restartable) { | 40 int SSLSocketAdapter::StartSSL(const char* hostname, bool restartable) { |
| 40 DCHECK(!restartable); | 41 DCHECK(!restartable); |
| 41 hostname_ = hostname; | 42 hostname_ = hostname; |
| 42 | 43 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 76 | 77 |
| 77 if (result == net::ERR_IO_PENDING || result == net::OK) { | 78 if (result == net::ERR_IO_PENDING || result == net::OK) { |
| 78 return 0; | 79 return 0; |
| 79 } else { | 80 } else { |
| 80 LOG(ERROR) << "Could not start SSL: " << net::ErrorToString(result); | 81 LOG(ERROR) << "Could not start SSL: " << net::ErrorToString(result); |
| 81 return result; | 82 return result; |
| 82 } | 83 } |
| 83 } | 84 } |
| 84 | 85 |
| 85 int SSLSocketAdapter::Send(const void* buf, size_t len) { | 86 int SSLSocketAdapter::Send(const void* buf, size_t len) { |
| 86 if (ssl_state_ != SSLSTATE_CONNECTED) { | 87 if (ssl_state_ == SSLSTATE_ERROR) { |
| 88 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
| |
| 89 return -1; | |
| 90 } 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.
| |
| 87 return AsyncSocketAdapter::Send(buf, len); | 91 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.
| |
| 88 } else { | 92 } |
| 89 scoped_refptr<net::IOBuffer> transport_buf(new net::IOBuffer(len)); | |
| 90 memcpy(transport_buf->data(), buf, len); | |
| 91 | 93 |
| 92 int result = ssl_socket_->Write(transport_buf, len, | 94 if (write_state_ == IOSTATE_PENDING) { |
| 93 net::CompletionCallback()); | 95 SetError(EWOULDBLOCK); |
| 94 if (result == net::ERR_IO_PENDING) { | 96 return -1; |
| 95 SetError(EWOULDBLOCK); | |
| 96 } | |
| 97 transport_buf = NULL; | |
| 98 return result; | |
| 99 } | 97 } |
| 98 | |
| 99 write_buffer_ = new net::DrainableIOBuffer(new net::IOBuffer(len), len); | |
| 100 memcpy(write_buffer_->data(), buf, len); | |
| 101 | |
| 102 DoWrite(); | |
| 103 | |
| 104 return len; | |
| 100 } | 105 } |
| 101 | 106 |
| 102 int SSLSocketAdapter::Recv(void* buf, size_t len) { | 107 int SSLSocketAdapter::Recv(void* buf, size_t len) { |
| 103 switch (ssl_state_) { | 108 switch (ssl_state_) { |
| 104 case SSLSTATE_NONE: | 109 case SSLSTATE_NONE: |
| 105 return AsyncSocketAdapter::Recv(buf, len); | 110 return AsyncSocketAdapter::Recv(buf, len); |
| 106 | 111 |
| 107 case SSLSTATE_WAIT: | 112 case SSLSTATE_WAIT: |
| 108 SetError(EWOULDBLOCK); | 113 SetError(EWOULDBLOCK); |
| 109 return -1; | 114 return -1; |
| 110 | 115 |
| 111 case SSLSTATE_CONNECTED: | 116 case SSLSTATE_CONNECTED: |
| 112 switch (read_state_) { | 117 switch (read_state_) { |
| 113 case IOSTATE_NONE: { | 118 case IOSTATE_NONE: { |
| 114 transport_buf_ = new net::IOBuffer(len); | 119 read_buffer_ = new net::IOBuffer(len); |
| 115 int result = ssl_socket_->Read( | 120 int result = ssl_socket_->Read( |
| 116 transport_buf_, len, | 121 read_buffer_, len, |
| 117 base::Bind(&SSLSocketAdapter::OnRead, base::Unretained(this))); | 122 base::Bind(&SSLSocketAdapter::OnRead, base::Unretained(this))); |
| 118 if (result >= 0) { | 123 if (result >= 0) { |
| 119 memcpy(buf, transport_buf_->data(), len); | 124 memcpy(buf, read_buffer_->data(), len); |
| 120 } | 125 } |
| 121 | 126 |
| 122 if (result == net::ERR_IO_PENDING) { | 127 if (result == net::ERR_IO_PENDING) { |
| 123 read_state_ = IOSTATE_PENDING; | 128 read_state_ = IOSTATE_PENDING; |
| 124 SetError(EWOULDBLOCK); | 129 SetError(EWOULDBLOCK); |
| 125 } else { | 130 } else { |
| 126 if (result < 0) { | 131 if (result < 0) { |
| 127 SetError(result); | 132 SetError(EINVAL); |
| 128 VLOG(1) << "Socket error " << result; | 133 ssl_state_ = SSLSTATE_ERROR; |
| 134 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.
| |
| 129 } | 135 } |
| 130 transport_buf_ = NULL; | 136 read_buffer_ = NULL; |
| 131 } | 137 } |
| 132 return result; | 138 return result; |
| 133 } | 139 } |
| 134 case IOSTATE_PENDING: | 140 case IOSTATE_PENDING: |
| 135 SetError(EWOULDBLOCK); | 141 SetError(EWOULDBLOCK); |
| 136 return -1; | 142 return -1; |
| 137 | 143 |
| 138 case IOSTATE_COMPLETE: | 144 case IOSTATE_COMPLETE: |
| 139 memcpy(buf, transport_buf_->data(), len); | 145 int size = std::min(read_buffer_size_ - read_buffer_position_, |
| 140 transport_buf_ = NULL; | 146 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.
| |
| 141 read_state_ = IOSTATE_NONE; | 147 memcpy(buf, read_buffer_->data() + read_buffer_position_, size); |
| 142 return data_transferred_; | 148 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
| |
| 149 if (read_buffer_position_ == read_buffer_size_) { | |
| 150 read_buffer_ = NULL; | |
| 151 read_state_ = IOSTATE_NONE; | |
| 152 } | |
| 153 return size; | |
| 143 } | 154 } |
| 155 | |
| 156 case SSLSTATE_ERROR: | |
| 157 SetError(EINVAL); | |
| 158 return -1; | |
| 144 } | 159 } |
| 145 | 160 |
| 146 NOTREACHED(); | 161 NOTREACHED(); |
| 147 return -1; | 162 return -1; |
| 148 } | 163 } |
| 149 | 164 |
| 150 void SSLSocketAdapter::OnConnected(int result) { | 165 void SSLSocketAdapter::OnConnected(int result) { |
| 151 if (result == net::OK) { | 166 if (result == net::OK) { |
| 152 ssl_state_ = SSLSTATE_CONNECTED; | 167 ssl_state_ = SSLSTATE_CONNECTED; |
| 153 OnConnectEvent(this); | 168 OnConnectEvent(this); |
| 154 } else { | 169 } else { |
| 155 LOG(WARNING) << "OnConnected failed with error " << result; | 170 LOG(WARNING) << "OnConnected failed with error " << result; |
| 156 } | 171 } |
| 157 } | 172 } |
| 158 | 173 |
| 159 void SSLSocketAdapter::OnRead(int result) { | 174 void SSLSocketAdapter::OnRead(int result) { |
| 160 DCHECK(read_state_ == IOSTATE_PENDING); | 175 DCHECK(read_state_ == IOSTATE_PENDING); |
| 161 read_state_ = IOSTATE_COMPLETE; | 176 if (result > 0) { |
| 162 data_transferred_ = result; | 177 read_state_ = IOSTATE_COMPLETE; |
| 178 read_buffer_size_ = result; | |
| 179 read_buffer_position_ = 0; | |
| 180 } else { | |
| 181 read_state_ = IOSTATE_NONE; | |
| 182 if (result < 0) { | |
| 183 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_
| |
| 184 } | |
| 185 } | |
| 163 AsyncSocketAdapter::OnReadEvent(this); | 186 AsyncSocketAdapter::OnReadEvent(this); |
| 164 } | 187 } |
| 165 | 188 |
| 166 void SSLSocketAdapter::OnWrite(int result) { | 189 void SSLSocketAdapter::OnWritten(int result) { |
| 167 DCHECK(write_state_ == IOSTATE_PENDING); | 190 DCHECK(write_state_ == IOSTATE_PENDING); |
| 168 write_state_ = IOSTATE_COMPLETE; | 191 write_state_ = IOSTATE_COMPLETE; |
| 169 data_transferred_ = result; | 192 if (result >= 0) { |
| 193 write_buffer_->DidConsume(result); | |
| 194 if (!write_buffer_->BytesRemaining()) { | |
| 195 write_buffer_ = NULL; | |
| 196 } else { | |
| 197 DoWrite(); | |
| 198 } | |
| 199 } else { | |
| 200 ssl_state_ = SSLSTATE_ERROR; | |
| 201 } | |
| 170 AsyncSocketAdapter::OnWriteEvent(this); | 202 AsyncSocketAdapter::OnWriteEvent(this); |
| 171 } | 203 } |
| 172 | 204 |
| 205 void SSLSocketAdapter::DoWrite() { | |
| 206 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.
| |
| 207 int result = ssl_socket_->Write( | |
| 208 write_buffer_, write_buffer_->BytesRemaining(), | |
| 209 base::Bind(&SSLSocketAdapter::OnWritten, base::Unretained(this))); | |
| 210 | |
| 211 if (result == net::ERR_IO_PENDING) { | |
| 212 write_state_ = IOSTATE_PENDING; | |
| 213 } else if (result < 0) { | |
| 214 SetError(EINVAL); | |
| 215 ssl_state_ = SSLSTATE_ERROR; | |
| 216 } else { | |
| 217 write_buffer_ = NULL; | |
| 218 } | |
| 219 } | |
| 220 | |
| 173 void SSLSocketAdapter::OnConnectEvent(talk_base::AsyncSocket* socket) { | 221 void SSLSocketAdapter::OnConnectEvent(talk_base::AsyncSocket* socket) { |
| 174 if (ssl_state_ != SSLSTATE_WAIT) { | 222 if (ssl_state_ != SSLSTATE_WAIT) { |
| 175 AsyncSocketAdapter::OnConnectEvent(socket); | 223 AsyncSocketAdapter::OnConnectEvent(socket); |
| 176 } else { | 224 } else { |
| 177 ssl_state_ = SSLSTATE_NONE; | 225 ssl_state_ = SSLSTATE_NONE; |
| 178 int result = BeginSSL(); | 226 int result = BeginSSL(); |
| 179 if (0 != result) { | 227 if (0 != result) { |
| 180 // TODO(zork): Handle this case gracefully. | 228 // TODO(zork): Handle this case gracefully. |
| 181 LOG(WARNING) << "BeginSSL() failed with " << result; | 229 LOG(WARNING) << "BeginSSL() failed with " << result; |
| 182 } | 230 } |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 368 write_buffer_len_ = buffer_len; | 416 write_buffer_len_ = buffer_len; |
| 369 return; | 417 return; |
| 370 } | 418 } |
| 371 } | 419 } |
| 372 was_used_to_convey_data_ = true; | 420 was_used_to_convey_data_ = true; |
| 373 callback.Run(result); | 421 callback.Run(result); |
| 374 } | 422 } |
| 375 } | 423 } |
| 376 | 424 |
| 377 } // namespace remoting | 425 } // namespace remoting |
| OLD | NEW |