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 |