| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "jingle/notifier/base/chrome_async_socket.h" | 5 #include "jingle/notifier/base/chrome_async_socket.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cstring> | 8 #include <cstring> |
| 9 #include <cstdlib> | 9 #include <cstdlib> |
| 10 | 10 |
| 11 #include "base/basictypes.h" | 11 #include "base/basictypes.h" |
| 12 #include "base/bind.h" |
| 12 #include "base/compiler_specific.h" | 13 #include "base/compiler_specific.h" |
| 13 #include "base/logging.h" | 14 #include "base/logging.h" |
| 14 #include "base/message_loop.h" | 15 #include "base/message_loop.h" |
| 15 #include "jingle/notifier/base/resolving_client_socket_factory.h" | 16 #include "jingle/notifier/base/resolving_client_socket_factory.h" |
| 16 #include "net/base/address_list.h" | 17 #include "net/base/address_list.h" |
| 17 #include "net/base/host_port_pair.h" | 18 #include "net/base/host_port_pair.h" |
| 18 #include "net/base/io_buffer.h" | 19 #include "net/base/io_buffer.h" |
| 19 #include "net/base/net_util.h" | 20 #include "net/base/net_util.h" |
| 20 #include "net/base/ssl_config_service.h" | 21 #include "net/base/ssl_config_service.h" |
| 21 #include "net/base/sys_addrinfo.h" | 22 #include "net/base/sys_addrinfo.h" |
| (...skipping 14 matching lines...) Expand all Loading... |
| 36 read_callback_(ALLOW_THIS_IN_INITIALIZER_LIST(this), | 37 read_callback_(ALLOW_THIS_IN_INITIALIZER_LIST(this), |
| 37 &ChromeAsyncSocket::ProcessReadDone), | 38 &ChromeAsyncSocket::ProcessReadDone), |
| 38 write_callback_(ALLOW_THIS_IN_INITIALIZER_LIST(this), | 39 write_callback_(ALLOW_THIS_IN_INITIALIZER_LIST(this), |
| 39 &ChromeAsyncSocket::ProcessWriteDone), | 40 &ChromeAsyncSocket::ProcessWriteDone), |
| 40 ssl_connect_callback_(ALLOW_THIS_IN_INITIALIZER_LIST(this), | 41 ssl_connect_callback_(ALLOW_THIS_IN_INITIALIZER_LIST(this), |
| 41 &ChromeAsyncSocket::ProcessSSLConnectDone), | 42 &ChromeAsyncSocket::ProcessSSLConnectDone), |
| 42 client_socket_factory_(client_socket_factory), | 43 client_socket_factory_(client_socket_factory), |
| 43 state_(STATE_CLOSED), | 44 state_(STATE_CLOSED), |
| 44 error_(ERROR_NONE), | 45 error_(ERROR_NONE), |
| 45 net_error_(net::OK), | 46 net_error_(net::OK), |
| 46 scoped_runnable_method_factory_( | 47 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), |
| 47 ALLOW_THIS_IN_INITIALIZER_LIST(this)), | |
| 48 read_state_(IDLE), | 48 read_state_(IDLE), |
| 49 read_buf_(new net::IOBufferWithSize(read_buf_size)), | 49 read_buf_(new net::IOBufferWithSize(read_buf_size)), |
| 50 read_start_(0U), | 50 read_start_(0U), |
| 51 read_end_(0U), | 51 read_end_(0U), |
| 52 write_state_(IDLE), | 52 write_state_(IDLE), |
| 53 write_buf_(new net::IOBufferWithSize(write_buf_size)), | 53 write_buf_(new net::IOBufferWithSize(write_buf_size)), |
| 54 write_end_(0U) { | 54 write_end_(0U) { |
| 55 DCHECK(client_socket_factory_.get()); | 55 DCHECK(client_socket_factory_.get()); |
| 56 DCHECK_GT(read_buf_size, 0U); | 56 DCHECK_GT(read_buf_size, 0U); |
| 57 DCHECK_GT(write_buf_size, 0U); | 57 DCHECK_GT(write_buf_size, 0U); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 DoNonNetError(ERROR_DNS); | 105 DoNonNetError(ERROR_DNS); |
| 106 return false; | 106 return false; |
| 107 } | 107 } |
| 108 | 108 |
| 109 DCHECK_EQ(state_, buzz::AsyncSocket::STATE_CLOSED); | 109 DCHECK_EQ(state_, buzz::AsyncSocket::STATE_CLOSED); |
| 110 DCHECK_EQ(read_state_, IDLE); | 110 DCHECK_EQ(read_state_, IDLE); |
| 111 DCHECK_EQ(write_state_, IDLE); | 111 DCHECK_EQ(write_state_, IDLE); |
| 112 | 112 |
| 113 state_ = STATE_CONNECTING; | 113 state_ = STATE_CONNECTING; |
| 114 | 114 |
| 115 DCHECK(scoped_runnable_method_factory_.empty()); | 115 DCHECK_EQ(false, weak_factory_.HasWeakPtrs()); |
| 116 scoped_runnable_method_factory_.RevokeAll(); | |
| 117 | 116 |
| 118 net::HostPortPair dest_host_port_pair(address.IPAsString(), address.port()); | 117 net::HostPortPair dest_host_port_pair(address.IPAsString(), address.port()); |
| 119 | 118 |
| 120 transport_socket_.reset( | 119 transport_socket_.reset( |
| 121 client_socket_factory_->CreateTransportClientSocket( | 120 client_socket_factory_->CreateTransportClientSocket( |
| 122 dest_host_port_pair)); | 121 dest_host_port_pair)); |
| 123 int status = transport_socket_->Connect(&connect_callback_); | 122 int status = transport_socket_->Connect(&connect_callback_); |
| 124 if (status != net::ERR_IO_PENDING) { | 123 if (status != net::ERR_IO_PENDING) { |
| 125 // We defer execution of ProcessConnectDone instead of calling it | 124 // We defer execution of ProcessConnectDone instead of calling it |
| 126 // directly here as the caller may not expect an error/close to | 125 // directly here as the caller may not expect an error/close to |
| 127 // happen here. This is okay, as from the caller's point of view, | 126 // happen here. This is okay, as from the caller's point of view, |
| 128 // the connect always happens asynchronously. | 127 // the connect always happens asynchronously. |
| 129 MessageLoop* message_loop = MessageLoop::current(); | 128 MessageLoop* message_loop = MessageLoop::current(); |
| 130 CHECK(message_loop); | 129 CHECK(message_loop); |
| 131 message_loop->PostTask( | 130 message_loop->PostTask(FROM_HERE, |
| 132 FROM_HERE, | 131 base::Bind(&ChromeAsyncSocket::ProcessConnectDone, |
| 133 scoped_runnable_method_factory_.NewRunnableMethod( | 132 weak_factory_.GetWeakPtr(), status)); |
| 134 &ChromeAsyncSocket::ProcessConnectDone, status)); | |
| 135 } | 133 } |
| 136 return true; | 134 return true; |
| 137 } | 135 } |
| 138 | 136 |
| 139 // STATE_CONNECTING -> STATE_OPEN | 137 // STATE_CONNECTING -> STATE_OPEN |
| 140 // read_state_ == IDLE -> read_state_ == POSTED (via PostDoRead()) | 138 // read_state_ == IDLE -> read_state_ == POSTED (via PostDoRead()) |
| 141 | 139 |
| 142 void ChromeAsyncSocket::ProcessConnectDone(int status) { | 140 void ChromeAsyncSocket::ProcessConnectDone(int status) { |
| 143 DCHECK_NE(status, net::ERR_IO_PENDING); | 141 DCHECK_NE(status, net::ERR_IO_PENDING); |
| 144 DCHECK_EQ(read_state_, IDLE); | 142 DCHECK_EQ(read_state_, IDLE); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 160 | 158 |
| 161 void ChromeAsyncSocket::PostDoRead() { | 159 void ChromeAsyncSocket::PostDoRead() { |
| 162 DCHECK(IsOpen()); | 160 DCHECK(IsOpen()); |
| 163 DCHECK_EQ(read_state_, IDLE); | 161 DCHECK_EQ(read_state_, IDLE); |
| 164 DCHECK_EQ(read_start_, 0U); | 162 DCHECK_EQ(read_start_, 0U); |
| 165 DCHECK_EQ(read_end_, 0U); | 163 DCHECK_EQ(read_end_, 0U); |
| 166 MessageLoop* message_loop = MessageLoop::current(); | 164 MessageLoop* message_loop = MessageLoop::current(); |
| 167 CHECK(message_loop); | 165 CHECK(message_loop); |
| 168 message_loop->PostTask( | 166 message_loop->PostTask( |
| 169 FROM_HERE, | 167 FROM_HERE, |
| 170 scoped_runnable_method_factory_.NewRunnableMethod( | 168 base::Bind(&ChromeAsyncSocket::DoRead, weak_factory_.GetWeakPtr())); |
| 171 &ChromeAsyncSocket::DoRead)); | |
| 172 read_state_ = POSTED; | 169 read_state_ = POSTED; |
| 173 } | 170 } |
| 174 | 171 |
| 175 // read_state_ == POSTED -> read_state_ == PENDING | 172 // read_state_ == POSTED -> read_state_ == PENDING |
| 176 | 173 |
| 177 void ChromeAsyncSocket::DoRead() { | 174 void ChromeAsyncSocket::DoRead() { |
| 178 DCHECK(IsOpen()); | 175 DCHECK(IsOpen()); |
| 179 DCHECK_EQ(read_state_, POSTED); | 176 DCHECK_EQ(read_state_, POSTED); |
| 180 DCHECK_EQ(read_start_, 0U); | 177 DCHECK_EQ(read_start_, 0U); |
| 181 DCHECK_EQ(read_end_, 0U); | 178 DCHECK_EQ(read_end_, 0U); |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 292 // write_state_ == IDLE -> write_state_ == POSTED | 289 // write_state_ == IDLE -> write_state_ == POSTED |
| 293 | 290 |
| 294 void ChromeAsyncSocket::PostDoWrite() { | 291 void ChromeAsyncSocket::PostDoWrite() { |
| 295 DCHECK(IsOpen()); | 292 DCHECK(IsOpen()); |
| 296 DCHECK_EQ(write_state_, IDLE); | 293 DCHECK_EQ(write_state_, IDLE); |
| 297 DCHECK_GT(write_end_, 0U); | 294 DCHECK_GT(write_end_, 0U); |
| 298 MessageLoop* message_loop = MessageLoop::current(); | 295 MessageLoop* message_loop = MessageLoop::current(); |
| 299 CHECK(message_loop); | 296 CHECK(message_loop); |
| 300 message_loop->PostTask( | 297 message_loop->PostTask( |
| 301 FROM_HERE, | 298 FROM_HERE, |
| 302 scoped_runnable_method_factory_.NewRunnableMethod( | 299 base::Bind(&ChromeAsyncSocket::DoWrite, weak_factory_.GetWeakPtr())); |
| 303 &ChromeAsyncSocket::DoWrite)); | |
| 304 write_state_ = POSTED; | 300 write_state_ = POSTED; |
| 305 } | 301 } |
| 306 | 302 |
| 307 // write_state_ == POSTED -> write_state_ == PENDING | 303 // write_state_ == POSTED -> write_state_ == PENDING |
| 308 | 304 |
| 309 void ChromeAsyncSocket::DoWrite() { | 305 void ChromeAsyncSocket::DoWrite() { |
| 310 DCHECK(IsOpen()); | 306 DCHECK(IsOpen()); |
| 311 DCHECK_EQ(write_state_, POSTED); | 307 DCHECK_EQ(write_state_, POSTED); |
| 312 DCHECK_GT(write_end_, 0U); | 308 DCHECK_GT(write_end_, 0U); |
| 313 // Once we call Write(), we cannot call StartTls() until the write | 309 // Once we call Write(), we cannot call StartTls() until the write |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 360 // * -> STATE_CLOSED | 356 // * -> STATE_CLOSED |
| 361 | 357 |
| 362 bool ChromeAsyncSocket::Close() { | 358 bool ChromeAsyncSocket::Close() { |
| 363 DoClose(); | 359 DoClose(); |
| 364 return true; | 360 return true; |
| 365 } | 361 } |
| 366 | 362 |
| 367 // (not STATE_CLOSED) -> STATE_CLOSED | 363 // (not STATE_CLOSED) -> STATE_CLOSED |
| 368 | 364 |
| 369 void ChromeAsyncSocket::DoClose() { | 365 void ChromeAsyncSocket::DoClose() { |
| 370 scoped_runnable_method_factory_.RevokeAll(); | 366 weak_factory_.InvalidateWeakPtrs(); |
| 371 if (transport_socket_.get()) { | 367 if (transport_socket_.get()) { |
| 372 transport_socket_->Disconnect(); | 368 transport_socket_->Disconnect(); |
| 373 } | 369 } |
| 374 transport_socket_.reset(); | 370 transport_socket_.reset(); |
| 375 read_state_ = IDLE; | 371 read_state_ = IDLE; |
| 376 read_start_ = 0U; | 372 read_start_ = 0U; |
| 377 read_end_ = 0U; | 373 read_end_ = 0U; |
| 378 write_state_ = IDLE; | 374 write_state_ = IDLE; |
| 379 write_end_ = 0U; | 375 write_end_ = 0U; |
| 380 if (state_ != STATE_CLOSED) { | 376 if (state_ != STATE_CLOSED) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 397 return false; | 393 return false; |
| 398 } | 394 } |
| 399 | 395 |
| 400 state_ = STATE_TLS_CONNECTING; | 396 state_ = STATE_TLS_CONNECTING; |
| 401 read_state_ = IDLE; | 397 read_state_ = IDLE; |
| 402 read_start_ = 0U; | 398 read_start_ = 0U; |
| 403 read_end_ = 0U; | 399 read_end_ = 0U; |
| 404 DCHECK_EQ(write_end_, 0U); | 400 DCHECK_EQ(write_end_, 0U); |
| 405 | 401 |
| 406 // Clear out any posted DoRead() tasks. | 402 // Clear out any posted DoRead() tasks. |
| 407 scoped_runnable_method_factory_.RevokeAll(); | 403 weak_factory_.InvalidateWeakPtrs(); |
| 408 | 404 |
| 409 DCHECK(transport_socket_.get()); | 405 DCHECK(transport_socket_.get()); |
| 410 net::ClientSocketHandle* socket_handle = new net::ClientSocketHandle(); | 406 net::ClientSocketHandle* socket_handle = new net::ClientSocketHandle(); |
| 411 socket_handle->set_socket(transport_socket_.release()); | 407 socket_handle->set_socket(transport_socket_.release()); |
| 412 transport_socket_.reset( | 408 transport_socket_.reset( |
| 413 client_socket_factory_->CreateSSLClientSocket( | 409 client_socket_factory_->CreateSSLClientSocket( |
| 414 socket_handle, net::HostPortPair(domain_name, 443))); | 410 socket_handle, net::HostPortPair(domain_name, 443))); |
| 415 int status = transport_socket_->Connect(&ssl_connect_callback_); | 411 int status = transport_socket_->Connect(&ssl_connect_callback_); |
| 416 if (status != net::ERR_IO_PENDING) { | 412 if (status != net::ERR_IO_PENDING) { |
| 417 MessageLoop* message_loop = MessageLoop::current(); | 413 MessageLoop* message_loop = MessageLoop::current(); |
| 418 CHECK(message_loop); | 414 CHECK(message_loop); |
| 419 message_loop->PostTask( | 415 message_loop->PostTask(FROM_HERE, |
| 420 FROM_HERE, | 416 base::Bind(&ChromeAsyncSocket::ProcessSSLConnectDone, |
| 421 scoped_runnable_method_factory_.NewRunnableMethod( | 417 weak_factory_.GetWeakPtr(), status)); |
| 422 &ChromeAsyncSocket::ProcessSSLConnectDone, status)); | |
| 423 } | 418 } |
| 424 return true; | 419 return true; |
| 425 } | 420 } |
| 426 | 421 |
| 427 // STATE_TLS_CONNECTING -> STATE_TLS_OPEN | 422 // STATE_TLS_CONNECTING -> STATE_TLS_OPEN |
| 428 // read_state_ == IDLE -> read_state_ == POSTED (via PostDoRead()) | 423 // read_state_ == IDLE -> read_state_ == POSTED (via PostDoRead()) |
| 429 // (maybe) write_state_ == IDLE -> write_state_ == POSTED (via | 424 // (maybe) write_state_ == IDLE -> write_state_ == POSTED (via |
| 430 // PostDoWrite()) | 425 // PostDoWrite()) |
| 431 | 426 |
| 432 void ChromeAsyncSocket::ProcessSSLConnectDone(int status) { | 427 void ChromeAsyncSocket::ProcessSSLConnectDone(int status) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 443 } | 438 } |
| 444 state_ = STATE_TLS_OPEN; | 439 state_ = STATE_TLS_OPEN; |
| 445 PostDoRead(); | 440 PostDoRead(); |
| 446 if (write_end_ > 0U) { | 441 if (write_end_ > 0U) { |
| 447 PostDoWrite(); | 442 PostDoWrite(); |
| 448 } | 443 } |
| 449 SignalSSLConnected(); | 444 SignalSSLConnected(); |
| 450 } | 445 } |
| 451 | 446 |
| 452 } // namespace notifier | 447 } // namespace notifier |
| OLD | NEW |