Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2010 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 #if defined(OS_WIN) | 7 #if defined(OS_WIN) |
|
akalin
2011/04/15 17:41:05
remove this block since you moved it to the unitte
sanjeevr
2011/04/15 18:04:33
Done.
| |
| 8 #include <winsock2.h> | 8 #include <winsock2.h> |
| 9 #elif defined(OS_POSIX) | 9 #elif defined(OS_POSIX) |
| 10 #include <arpa/inet.h> | 10 #include <arpa/inet.h> |
| 11 #endif | 11 #endif |
| 12 | 12 |
| 13 #include <algorithm> | 13 #include <algorithm> |
| 14 #include <cstring> | 14 #include <cstring> |
| 15 #include <cstdlib> | 15 #include <cstdlib> |
| 16 | 16 |
| 17 #include "base/basictypes.h" | 17 #include "base/basictypes.h" |
| 18 #include "base/compiler_specific.h" | 18 #include "base/compiler_specific.h" |
| 19 #include "base/logging.h" | 19 #include "base/logging.h" |
| 20 #include "base/message_loop.h" | 20 #include "base/message_loop.h" |
| 21 #include "jingle/notifier/base/resolving_client_socket_factory.h" | |
| 21 #include "net/base/address_list.h" | 22 #include "net/base/address_list.h" |
| 22 #include "net/base/host_port_pair.h" | 23 #include "net/base/host_port_pair.h" |
| 23 #include "net/base/io_buffer.h" | 24 #include "net/base/io_buffer.h" |
| 24 #include "net/base/net_util.h" | 25 #include "net/base/net_util.h" |
| 25 #include "net/base/ssl_config_service.h" | 26 #include "net/base/ssl_config_service.h" |
| 26 #include "net/base/sys_addrinfo.h" | 27 #include "net/base/sys_addrinfo.h" |
| 27 #include "net/socket/client_socket_factory.h" | 28 #include "net/socket/client_socket_factory.h" |
| 29 #include "net/socket/client_socket_handle.h" | |
| 28 #include "net/socket/ssl_client_socket.h" | 30 #include "net/socket/ssl_client_socket.h" |
| 29 #include "net/socket/tcp_client_socket.h" | 31 #include "net/socket/tcp_client_socket.h" |
| 30 #include "talk/base/socketaddress.h" | 32 #include "talk/base/socketaddress.h" |
| 31 | 33 |
| 32 namespace notifier { | 34 namespace notifier { |
| 33 | 35 |
| 34 ChromeAsyncSocket::ChromeAsyncSocket( | 36 ChromeAsyncSocket::ChromeAsyncSocket( |
| 35 net::ClientSocketFactory* client_socket_factory, | 37 ResolvingClientSocketFactory* client_socket_factory, |
| 36 const net::SSLConfig& ssl_config, | |
| 37 net::CertVerifier* cert_verifier, | |
| 38 size_t read_buf_size, | 38 size_t read_buf_size, |
| 39 size_t write_buf_size, | 39 size_t write_buf_size, |
| 40 net::NetLog* net_log) | 40 net::NetLog* net_log) |
| 41 : connect_callback_(ALLOW_THIS_IN_INITIALIZER_LIST(this), | 41 : connect_callback_(ALLOW_THIS_IN_INITIALIZER_LIST(this), |
| 42 &ChromeAsyncSocket::ProcessConnectDone), | 42 &ChromeAsyncSocket::ProcessConnectDone), |
| 43 read_callback_(ALLOW_THIS_IN_INITIALIZER_LIST(this), | 43 read_callback_(ALLOW_THIS_IN_INITIALIZER_LIST(this), |
| 44 &ChromeAsyncSocket::ProcessReadDone), | 44 &ChromeAsyncSocket::ProcessReadDone), |
| 45 write_callback_(ALLOW_THIS_IN_INITIALIZER_LIST(this), | 45 write_callback_(ALLOW_THIS_IN_INITIALIZER_LIST(this), |
| 46 &ChromeAsyncSocket::ProcessWriteDone), | 46 &ChromeAsyncSocket::ProcessWriteDone), |
| 47 ssl_connect_callback_(ALLOW_THIS_IN_INITIALIZER_LIST(this), | 47 ssl_connect_callback_(ALLOW_THIS_IN_INITIALIZER_LIST(this), |
| 48 &ChromeAsyncSocket::ProcessSSLConnectDone), | 48 &ChromeAsyncSocket::ProcessSSLConnectDone), |
| 49 client_socket_factory_(client_socket_factory), | 49 client_socket_factory_(client_socket_factory), |
| 50 ssl_config_(ssl_config), | |
| 51 cert_verifier_(cert_verifier), | |
| 52 bound_net_log_( | 50 bound_net_log_( |
| 53 net::BoundNetLog::Make(net_log, net::NetLog::SOURCE_SOCKET)), | 51 net::BoundNetLog::Make(net_log, net::NetLog::SOURCE_SOCKET)), |
| 54 state_(STATE_CLOSED), | 52 state_(STATE_CLOSED), |
| 55 error_(ERROR_NONE), | 53 error_(ERROR_NONE), |
| 56 net_error_(net::OK), | 54 net_error_(net::OK), |
| 57 scoped_runnable_method_factory_( | 55 scoped_runnable_method_factory_( |
| 58 ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 56 ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
| 59 read_state_(IDLE), | 57 read_state_(IDLE), |
| 60 read_buf_(new net::IOBufferWithSize(read_buf_size)), | 58 read_buf_(new net::IOBufferWithSize(read_buf_size)), |
| 61 read_start_(0U), | 59 read_start_(0U), |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 96 void ChromeAsyncSocket::DoNetError(net::Error net_error) { | 94 void ChromeAsyncSocket::DoNetError(net::Error net_error) { |
| 97 error_ = ERROR_WINSOCK; | 95 error_ = ERROR_WINSOCK; |
| 98 net_error_ = net_error; | 96 net_error_ = net_error; |
| 99 } | 97 } |
| 100 | 98 |
| 101 void ChromeAsyncSocket::DoNetErrorFromStatus(int status) { | 99 void ChromeAsyncSocket::DoNetErrorFromStatus(int status) { |
| 102 DCHECK_LT(status, net::OK); | 100 DCHECK_LT(status, net::OK); |
| 103 DoNetError(static_cast<net::Error>(status)); | 101 DoNetError(static_cast<net::Error>(status)); |
| 104 } | 102 } |
| 105 | 103 |
| 106 namespace { | |
| 107 | |
| 108 // Takes a 32-bit integer in host byte order and converts it to a | |
| 109 // net::IPAddressNumber. | |
| 110 net::IPAddressNumber Uint32ToIPAddressNumber(uint32 ip) { | |
| 111 uint32 ip_nbo = htonl(ip); | |
| 112 const unsigned char* const ip_start = | |
| 113 reinterpret_cast<const unsigned char*>(&ip_nbo); | |
| 114 return net::IPAddressNumber(ip_start, ip_start + (sizeof ip_nbo)); | |
| 115 } | |
| 116 | |
| 117 net::AddressList SocketAddressToAddressList( | |
| 118 const talk_base::SocketAddress& address) { | |
| 119 DCHECK_NE(address.ip(), 0U); | |
| 120 return net::AddressList(Uint32ToIPAddressNumber(address.ip()), | |
| 121 address.port(), false); | |
| 122 } | |
| 123 | |
| 124 } // namespace | |
| 125 | |
| 126 // STATE_CLOSED -> STATE_CONNECTING | 104 // STATE_CLOSED -> STATE_CONNECTING |
| 127 | 105 |
| 128 bool ChromeAsyncSocket::Connect(const talk_base::SocketAddress& address) { | 106 bool ChromeAsyncSocket::Connect(const talk_base::SocketAddress& address) { |
| 129 if (state_ != STATE_CLOSED) { | 107 if (state_ != STATE_CLOSED) { |
| 130 LOG(DFATAL) << "Connect() called on non-closed socket"; | 108 LOG(DFATAL) << "Connect() called on non-closed socket"; |
| 131 DoNonNetError(ERROR_WRONGSTATE); | 109 DoNonNetError(ERROR_WRONGSTATE); |
| 132 return false; | 110 return false; |
| 133 } | 111 } |
| 134 if (address.ip() == 0) { | 112 // We can't work with an empty hostname and IP address. |
| 113 if (address.hostname().empty() && (address.ip() == 0)) { | |
| 135 DoNonNetError(ERROR_DNS); | 114 DoNonNetError(ERROR_DNS); |
| 136 return false; | 115 return false; |
| 137 } | 116 } |
| 138 | 117 |
| 139 DCHECK_EQ(state_, buzz::AsyncSocket::STATE_CLOSED); | 118 DCHECK_EQ(state_, buzz::AsyncSocket::STATE_CLOSED); |
| 140 DCHECK_EQ(read_state_, IDLE); | 119 DCHECK_EQ(read_state_, IDLE); |
| 141 DCHECK_EQ(write_state_, IDLE); | 120 DCHECK_EQ(write_state_, IDLE); |
| 142 | 121 |
| 143 state_ = STATE_CONNECTING; | 122 state_ = STATE_CONNECTING; |
| 144 | 123 |
| 145 DCHECK(scoped_runnable_method_factory_.empty()); | 124 DCHECK(scoped_runnable_method_factory_.empty()); |
| 146 scoped_runnable_method_factory_.RevokeAll(); | 125 scoped_runnable_method_factory_.RevokeAll(); |
| 147 | 126 |
| 148 net::AddressList address_list = SocketAddressToAddressList(address); | 127 net::HostPortPair dest_host_port_pair(address.IPAsString(), address.port()); |
| 128 | |
| 149 transport_socket_.reset( | 129 transport_socket_.reset( |
| 150 client_socket_factory_->CreateTransportClientSocket( | 130 client_socket_factory_->CreateTransportClientSocket( |
| 151 address_list, bound_net_log_.net_log(), net::NetLog::Source())); | 131 dest_host_port_pair, bound_net_log_.net_log())); |
| 152 int status = transport_socket_->Connect(&connect_callback_); | 132 int status = transport_socket_->Connect(&connect_callback_); |
| 153 if (status != net::ERR_IO_PENDING) { | 133 if (status != net::ERR_IO_PENDING) { |
| 154 // We defer execution of ProcessConnectDone instead of calling it | 134 // We defer execution of ProcessConnectDone instead of calling it |
| 155 // directly here as the caller may not expect an error/close to | 135 // directly here as the caller may not expect an error/close to |
| 156 // happen here. This is okay, as from the caller's point of view, | 136 // happen here. This is okay, as from the caller's point of view, |
| 157 // the connect always happens asynchronously. | 137 // the connect always happens asynchronously. |
| 158 MessageLoop* message_loop = MessageLoop::current(); | 138 MessageLoop* message_loop = MessageLoop::current(); |
| 159 CHECK(message_loop); | 139 CHECK(message_loop); |
| 160 message_loop->PostTask( | 140 message_loop->PostTask( |
| 161 FROM_HERE, | 141 FROM_HERE, |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 429 state_ = STATE_TLS_CONNECTING; | 409 state_ = STATE_TLS_CONNECTING; |
| 430 read_state_ = IDLE; | 410 read_state_ = IDLE; |
| 431 read_start_ = 0U; | 411 read_start_ = 0U; |
| 432 read_end_ = 0U; | 412 read_end_ = 0U; |
| 433 DCHECK_EQ(write_end_, 0U); | 413 DCHECK_EQ(write_end_, 0U); |
| 434 | 414 |
| 435 // Clear out any posted DoRead() tasks. | 415 // Clear out any posted DoRead() tasks. |
| 436 scoped_runnable_method_factory_.RevokeAll(); | 416 scoped_runnable_method_factory_.RevokeAll(); |
| 437 | 417 |
| 438 DCHECK(transport_socket_.get()); | 418 DCHECK(transport_socket_.get()); |
| 419 net::ClientSocketHandle* socket_handle = new net::ClientSocketHandle(); | |
| 420 socket_handle->set_socket(transport_socket_.release()); | |
| 439 transport_socket_.reset( | 421 transport_socket_.reset( |
| 440 client_socket_factory_->CreateSSLClientSocket( | 422 client_socket_factory_->CreateSSLClientSocket( |
| 441 transport_socket_.release(), net::HostPortPair(domain_name, 443), | 423 socket_handle, net::HostPortPair(domain_name, 443))); |
| 442 ssl_config_, NULL /* ssl_host_info */, | |
| 443 cert_verifier_)); | |
| 444 int status = transport_socket_->Connect(&ssl_connect_callback_); | 424 int status = transport_socket_->Connect(&ssl_connect_callback_); |
| 445 if (status != net::ERR_IO_PENDING) { | 425 if (status != net::ERR_IO_PENDING) { |
| 446 MessageLoop* message_loop = MessageLoop::current(); | 426 MessageLoop* message_loop = MessageLoop::current(); |
| 447 CHECK(message_loop); | 427 CHECK(message_loop); |
| 448 message_loop->PostTask( | 428 message_loop->PostTask( |
| 449 FROM_HERE, | 429 FROM_HERE, |
| 450 scoped_runnable_method_factory_.NewRunnableMethod( | 430 scoped_runnable_method_factory_.NewRunnableMethod( |
| 451 &ChromeAsyncSocket::ProcessSSLConnectDone, status)); | 431 &ChromeAsyncSocket::ProcessSSLConnectDone, status)); |
| 452 } | 432 } |
| 453 return true; | 433 return true; |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 472 } | 452 } |
| 473 state_ = STATE_TLS_OPEN; | 453 state_ = STATE_TLS_OPEN; |
| 474 PostDoRead(); | 454 PostDoRead(); |
| 475 if (write_end_ > 0U) { | 455 if (write_end_ > 0U) { |
| 476 PostDoWrite(); | 456 PostDoWrite(); |
| 477 } | 457 } |
| 478 SignalSSLConnected(); | 458 SignalSSLConnected(); |
| 479 } | 459 } |
| 480 | 460 |
| 481 } // namespace notifier | 461 } // namespace notifier |
| OLD | NEW |