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

Side by Side Diff: jingle/notifier/communicator/single_login_attempt.cc

Issue 3300030: Removed use of XmppSocketAdapter by sync. (Closed) Base URL: http://git.chromium.org/git/chromium.git
Patch Set: Created 10 years, 3 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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 <algorithm> 5 #include <algorithm>
6 #include <cstddef> 6 #include <cstddef>
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include "jingle/notifier/communicator/single_login_attempt.h" 10 #include "jingle/notifier/communicator/single_login_attempt.h"
11 11
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "jingle/notifier/base/chrome_async_socket.h" 13 #include "jingle/notifier/base/chrome_async_socket.h"
14 #include "jingle/notifier/base/xmpp_client_socket_factory.h" 14 #include "jingle/notifier/base/xmpp_client_socket_factory.h"
15 #include "jingle/notifier/communicator/connection_options.h" 15 #include "jingle/notifier/communicator/connection_options.h"
16 #include "jingle/notifier/communicator/connection_settings.h" 16 #include "jingle/notifier/communicator/connection_settings.h"
17 #include "jingle/notifier/communicator/const_communicator.h" 17 #include "jingle/notifier/communicator/const_communicator.h"
18 #include "jingle/notifier/communicator/gaia_token_pre_xmpp_auth.h" 18 #include "jingle/notifier/communicator/gaia_token_pre_xmpp_auth.h"
19 #include "jingle/notifier/communicator/login_failure.h" 19 #include "jingle/notifier/communicator/login_failure.h"
20 #include "jingle/notifier/communicator/login_settings.h" 20 #include "jingle/notifier/communicator/login_settings.h"
21 #include "jingle/notifier/communicator/product_info.h"
22 #include "jingle/notifier/communicator/xmpp_connection_generator.h" 21 #include "jingle/notifier/communicator/xmpp_connection_generator.h"
23 #include "jingle/notifier/communicator/xmpp_socket_adapter.h"
24 #include "net/base/ssl_config_service.h" 22 #include "net/base/ssl_config_service.h"
25 #include "net/socket/client_socket_factory.h" 23 #include "net/socket/client_socket_factory.h"
26 #include "talk/base/asynchttprequest.h"
27 #include "talk/base/firewallsocketserver.h"
28 #include "talk/base/signalthread.h"
29 #include "talk/base/taskrunner.h"
30 #include "talk/base/win32socketinit.h"
31 #include "talk/xmllite/xmlelement.h" 24 #include "talk/xmllite/xmlelement.h"
32 #include "talk/xmpp/xmppclient.h" 25 #include "talk/xmpp/xmppclient.h"
33 #include "talk/xmpp/xmppclientsettings.h" 26 #include "talk/xmpp/xmppclientsettings.h"
34 #include "talk/xmpp/constants.h" 27 #include "talk/xmpp/constants.h"
35 28
36 namespace net { 29 namespace net {
37 class NetLog; 30 class NetLog;
38 } // namespace net 31 } // namespace net
39 32
40 namespace notifier { 33 namespace notifier {
(...skipping 13 matching lines...) Expand all
54 *stream_error = NULL; 47 *stream_error = NULL;
55 if (*error == buzz::XmppEngine::ERROR_STREAM) { 48 if (*error == buzz::XmppEngine::ERROR_STREAM) {
56 const buzz::XmlElement* error_element = client->GetStreamError(); 49 const buzz::XmlElement* error_element = client->GetStreamError();
57 if (error_element) { 50 if (error_element) {
58 *stream_error = new buzz::XmlElement(*error_element); 51 *stream_error = new buzz::XmlElement(*error_element);
59 } 52 }
60 } 53 }
61 } 54 }
62 55
63 SingleLoginAttempt::SingleLoginAttempt(talk_base::TaskParent* parent, 56 SingleLoginAttempt::SingleLoginAttempt(talk_base::TaskParent* parent,
64 LoginSettings* login_settings, 57 LoginSettings* login_settings)
65 bool use_chrome_async_socket,
66 bool successful_connection)
67 : talk_base::Task(parent), 58 : talk_base::Task(parent),
68 use_chrome_async_socket_(use_chrome_async_socket),
69 state_(buzz::XmppEngine::STATE_NONE), 59 state_(buzz::XmppEngine::STATE_NONE),
70 code_(buzz::XmppEngine::ERROR_NONE), 60 code_(buzz::XmppEngine::ERROR_NONE),
71 subcode_(0), 61 subcode_(0),
72 need_authentication_(false), 62 need_authentication_(false),
73 certificate_expired_(false), 63 certificate_expired_(false),
74 cookie_refreshed_(false),
75 successful_connection_(successful_connection),
76 login_settings_(login_settings), 64 login_settings_(login_settings),
77 client_(NULL) { 65 client_(NULL) {
78 #if defined(OS_WIN)
79 talk_base::EnsureWinsockInit();
80 #endif
81 connection_generator_.reset(new XmppConnectionGenerator( 66 connection_generator_.reset(new XmppConnectionGenerator(
82 this, 67 this,
83 login_settings_->host_resolver(), 68 login_settings_->host_resolver(),
84 &login_settings_->connection_options(), 69 &login_settings_->connection_options(),
85 login_settings_->try_ssltcp_first(), 70 login_settings_->try_ssltcp_first(),
86 login_settings_->proxy_only(), 71 login_settings_->proxy_only(),
87 login_settings_->server_list(), 72 login_settings_->server_list(),
88 login_settings_->server_count())); 73 login_settings_->server_count()));
89 74
90 connection_generator_->SignalExhaustedSettings.connect( 75 connection_generator_->SignalExhaustedSettings.connect(
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 return; 132 return;
148 } 133 }
149 134
150 if (!successfully_resolved_dns) { 135 if (!successfully_resolved_dns) {
151 code_ = buzz::XmppEngine::ERROR_SOCKET; 136 code_ = buzz::XmppEngine::ERROR_SOCKET;
152 subcode_ = first_dns_error; 137 subcode_ = first_dns_error;
153 } 138 }
154 139
155 LOG(INFO) << "Connection failed with error " << code_; 140 LOG(INFO) << "Connection failed with error " << code_;
156 141
157 // We were connected and we had a problem. 142 SignalNeedAutoReconnect();
158 if (successful_connection_) {
159 SignalNeedAutoReconnect();
160 // Expect to be deleted at this point.
161 return;
162 }
163
164 DiagnoseConnectionError();
165 } 143 }
166 144
167 void SingleLoginAttempt::UseNextConnection() { 145 void SingleLoginAttempt::UseNextConnection() {
168 DCHECK(connection_generator_.get()); 146 DCHECK(connection_generator_.get());
169 ClearClient(); 147 ClearClient();
170 connection_generator_->UseNextConnection(); 148 connection_generator_->UseNextConnection();
171 } 149 }
172 150
173 void SingleLoginAttempt::UseCurrentConnection() { 151 void SingleLoginAttempt::UseCurrentConnection() {
174 DCHECK(connection_generator_.get()); 152 DCHECK(connection_generator_.get());
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 need_authentication_ = true; 196 need_authentication_ = true;
219 } 197 }
220 198
221 void SingleLoginAttempt::OnCertificateExpired() { 199 void SingleLoginAttempt::OnCertificateExpired() {
222 // We can check this flag later if all connection options fail. 200 // We can check this flag later if all connection options fail.
223 certificate_expired_ = true; 201 certificate_expired_ = true;
224 } 202 }
225 203
226 buzz::AsyncSocket* SingleLoginAttempt::CreateSocket( 204 buzz::AsyncSocket* SingleLoginAttempt::CreateSocket(
227 const buzz::XmppClientSettings& xcs) { 205 const buzz::XmppClientSettings& xcs) {
228 if (use_chrome_async_socket_) { 206 bool use_fake_ssl_client_socket =
229 bool use_fake_ssl_client_socket = 207 (xcs.protocol() == cricket::PROTO_SSLTCP);
230 (xcs.protocol() == cricket::PROTO_SSLTCP); 208 net::ClientSocketFactory* const client_socket_factory =
231 net::ClientSocketFactory* const client_socket_factory = 209 new XmppClientSocketFactory(
232 new XmppClientSocketFactory( 210 net::ClientSocketFactory::GetDefaultFactory(),
233 net::ClientSocketFactory::GetDefaultFactory(), 211 use_fake_ssl_client_socket);
234 use_fake_ssl_client_socket); 212 // The default SSLConfig is good enough for us for now.
235 // The default SSLConfig is good enough for us for now. 213 const net::SSLConfig ssl_config;
236 const net::SSLConfig ssl_config; 214 // A read buffer of 64k ought to be sufficient.
237 // A read buffer of 64k ought to be sufficient. 215 const size_t kReadBufSize = 64U * 1024U;
238 const size_t kReadBufSize = 64U * 1024U; 216 // This number was taken from a similar number in
239 // This number was taken from a similar number in 217 // XmppSocketAdapter.
240 // XmppSocketAdapter. 218 const size_t kWriteBufSize = 64U * 1024U;
241 const size_t kWriteBufSize = 64U * 1024U; 219 // TODO(akalin): Use a real NetLog.
242 // TODO(akalin): Use a real NetLog. 220 net::NetLog* const net_log = NULL;
243 net::NetLog* const net_log = NULL; 221 return new ChromeAsyncSocket(
244 return new ChromeAsyncSocket( 222 client_socket_factory, ssl_config,
245 client_socket_factory, ssl_config, 223 kReadBufSize, kWriteBufSize, net_log);
246 kReadBufSize, kWriteBufSize, net_log);
247 }
248 // TODO(akalin): Always use ChromeAsyncSocket and get rid of this
249 // code.
250 bool allow_unverified_certs =
251 login_settings_->connection_options().allow_unverified_certs();
252 XmppSocketAdapter* adapter = new XmppSocketAdapter(xcs,
253 allow_unverified_certs);
254 adapter->SignalAuthenticationError.connect(
255 this,
256 &SingleLoginAttempt::OnAuthenticationError);
257 if (login_settings_->firewall()) {
258 adapter->set_firewall(true);
259 }
260 return adapter;
261 } 224 }
262 225
263 buzz::PreXmppAuth* SingleLoginAttempt::CreatePreXmppAuth( 226 buzz::PreXmppAuth* SingleLoginAttempt::CreatePreXmppAuth(
264 const buzz::XmppClientSettings& xcs) { 227 const buzz::XmppClientSettings& xcs) {
265 buzz::Jid jid(xcs.user(), xcs.host(), buzz::STR_EMPTY); 228 buzz::Jid jid(xcs.user(), xcs.host(), buzz::STR_EMPTY);
266 return new GaiaTokenPreXmppAuth( 229 return new GaiaTokenPreXmppAuth(
267 jid.Str(), xcs.auth_cookie(), xcs.token_service()); 230 jid.Str(), xcs.auth_cookie(), xcs.token_service());
268 } 231 }
269 232
270 void SingleLoginAttempt::OnFreshAuthCookie(const std::string& auth_cookie) {
271 // Remember this is a fresh cookie.
272 cookie_refreshed_ = true;
273
274 // TODO(sync): do the cookie logic (part of which is in the #if 0 below).
275
276 // The following code is what PhoneWindow does for the equivalent method.
277 #if 0
278 // Save cookie
279 AccountInfo current(account_history_.current());
280 current.set_auth_cookie(auth_cookie);
281 account_history_.set_current(current);
282
283 // Calc next time to refresh cookie, between 5 and 10 days. The cookie has
284 // 14 days of life; this gives at least 4 days of retries before the current
285 // cookie expires, maximizing the chance of having a valid cookie next time
286 // the connection servers go down.
287 FTULL now;
288
289 // NOTE: The following line is win32. Address this when implementing this
290 // code (doing "the cookie logic").
291 GetSystemTimeAsFileTime(&(now.ft));
292 ULONGLONG five_days = (ULONGLONG)10000 * 1000 * 60 * 60 * 24 * 5; // 5 days
293 ULONGLONG random = (ULONGLONG)10000 * // get to 100 ns units
294 ((rand() % (5 * 24 * 60)) * (60 * 1000) + // random min. in 5 day period
295 (rand() % 1000) * 60); // random 1/1000th of a minute
296 next_cookie_refresh_ = now.ull + five_days + random; // 5-10 days
297 #endif
298 }
299
300 void SingleLoginAttempt::DiagnoseConnectionError() {
301 switch (code_) {
302 case buzz::XmppEngine::ERROR_MISSING_USERNAME:
303 case buzz::XmppEngine::ERROR_NETWORK_TIMEOUT:
304 case buzz::XmppEngine::ERROR_DOCUMENT_CLOSED:
305 case buzz::XmppEngine::ERROR_BIND:
306 case buzz::XmppEngine::ERROR_AUTH:
307 case buzz::XmppEngine::ERROR_TLS:
308 case buzz::XmppEngine::ERROR_UNAUTHORIZED:
309 case buzz::XmppEngine::ERROR_VERSION:
310 case buzz::XmppEngine::ERROR_STREAM:
311 case buzz::XmppEngine::ERROR_XML:
312 case buzz::XmppEngine::ERROR_NONE:
313 default: {
314 LoginFailure failure(LoginFailure::XMPP_ERROR, code_, subcode_);
315 SignalLoginFailure(failure);
316 return;
317 }
318
319 // The following errors require diagnosistics:
320 // * spurious close of connection
321 // * socket errors after auth
322 case buzz::XmppEngine::ERROR_CONNECTION_CLOSED:
323 case buzz::XmppEngine::ERROR_SOCKET:
324 break;
325 }
326
327 talk_base::AsyncHttpRequest *http_request =
328 new talk_base::AsyncHttpRequest(GetUserAgentString());
329 http_request->set_host("www.google.com");
330 http_request->set_port(80);
331 http_request->set_secure(false);
332 http_request->request().path = "/";
333 http_request->request().verb = talk_base::HV_GET;
334
335 talk_base::ProxyInfo proxy;
336 DCHECK(connection_generator_.get());
337 if (connection_generator_.get()) {
338 proxy = connection_generator_->proxy();
339 }
340 http_request->set_proxy(proxy);
341 http_request->set_firewall(login_settings_->firewall());
342
343 http_request->SignalWorkDone.connect(this,
344 &SingleLoginAttempt::OnHttpTestDone);
345 http_request->Start();
346 http_request->Release();
347 }
348
349 void SingleLoginAttempt::OnHttpTestDone(talk_base::SignalThread* thread) {
350 DCHECK(thread);
351
352 talk_base::AsyncHttpRequest* request =
353 static_cast<talk_base::AsyncHttpRequest*>(thread);
354
355 if (request->response().scode == 200) {
356 // We were able to do an HTTP GET of www.google.com:80
357
358 //
359 // The original error should be reported
360 //
361 LoginFailure failure(LoginFailure::XMPP_ERROR, code_, subcode_);
362 SignalLoginFailure(failure);
363 return;
364 }
365
366 // Otherwise lets transmute the error into ERROR_SOCKET, and put the subcode
367 // as an indicator of what we think the problem might be.
368
369 #if 0
370 // TODO(sync): determine if notifier has an analogous situation.
371
372 //
373 // We weren't able to do an HTTP GET of www.google.com:80
374 //
375 GAutoupdater::Version version_logged_in(g_options.version_logged_in());
376 GAutoupdater::Version version_installed(GetProductVersion().c_str());
377 if (version_logged_in < version_installed) {
378 //
379 // Google Talk has been updated and can no longer connect to the Google
380 // Talk Service. Your firewall is probably not allowing the new version of
381 // Google Talk to connect to the internet. Please adjust your firewall
382 // settings to allow the new version of Google Talk to connect to the
383 // internet.
384 //
385 // We'll use the "error=1" to help figure this out for now.
386 //
387 LoginFailure failure(LoginFailure::XMPP_ERROR,
388 buzz::XmppEngine::ERROR_SOCKET,
389 1);
390 SignalLoginFailure(failure);
391 return;
392 }
393 #endif
394
395 //
396 // Any other checking we can add here?
397 //
398
399 //
400 // Google Talk is unable to use your internet connection. Either your network
401 // isn't configured or Google Talk is being blocked by a local firewall.
402 //
403 // We'll use the "error=0" to help figure this out for now
404 //
405 LoginFailure failure(LoginFailure::XMPP_ERROR,
406 buzz::XmppEngine::ERROR_SOCKET,
407 0);
408 SignalLoginFailure(failure);
409 }
410
411 void SingleLoginAttempt::OnClientStateChange(buzz::XmppEngine::State state) { 233 void SingleLoginAttempt::OnClientStateChange(buzz::XmppEngine::State state) {
412 if (state_ == state) 234 if (state_ == state)
413 return; 235 return;
414 236
415 buzz::XmppEngine::State previous_state = state_; 237 buzz::XmppEngine::State previous_state = state_;
416 state_ = state; 238 state_ = state;
417 239
418 switch (state) { 240 switch (state) {
419 case buzz::XmppEngine::STATE_NONE: 241 case buzz::XmppEngine::STATE_NONE:
420 case buzz::XmppEngine::STATE_START: 242 case buzz::XmppEngine::STATE_START:
421 case buzz::XmppEngine::STATE_OPENING: 243 case buzz::XmppEngine::STATE_OPENING:
244 case buzz::XmppEngine::STATE_OPEN:
422 // Do nothing. 245 // Do nothing.
423 break; 246 break;
424 case buzz::XmppEngine::STATE_OPEN:
425 successful_connection_ = true;
426 break;
427 case buzz::XmppEngine::STATE_CLOSED: 247 case buzz::XmppEngine::STATE_CLOSED:
428 OnClientStateChangeClosed(previous_state); 248 OnClientStateChangeClosed(previous_state);
429 break; 249 break;
430 } 250 }
431 SignalClientStateChange(state); 251 SignalClientStateChange(state);
432 if (state_ == buzz::XmppEngine::STATE_CLOSED) { 252 if (state_ == buzz::XmppEngine::STATE_CLOSED) {
433 OnClientStateChange(buzz::XmppEngine::STATE_NONE); 253 OnClientStateChange(buzz::XmppEngine::STATE_NONE);
434 } 254 }
435 } 255 }
436 256
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
492 // There was a problem with credentials (username/password). 312 // There was a problem with credentials (username/password).
493 HandleConnectionPasswordError(); 313 HandleConnectionPasswordError();
494 return; 314 return;
495 } 315 }
496 316
497 // Unexpected disconnect, 317 // Unexpected disconnect,
498 // Unreachable host, 318 // Unreachable host,
499 // Or internal server binding error - 319 // Or internal server binding error -
500 // All these are temporary problems, so continue reconnecting. 320 // All these are temporary problems, so continue reconnecting.
501 321
502 // GaiaAuth signals this directly via SignalCertificateExpired, but
503 // SChannelAdapter propagates the error through SocketWindow as a socket
504 // error.
505 if (code_ == buzz::XmppEngine::ERROR_SOCKET &&
506 subcode_ == SEC_E_CERT_EXPIRED) {
507 certificate_expired_ = true;
508 }
509
510 login_settings_->modifiable_user_settings()->set_resource(""); 322 login_settings_->modifiable_user_settings()->set_resource("");
511 323
512 // Look for stream::error server redirection stanza "see-other-host". 324 // Look for stream::error server redirection stanza "see-other-host".
513 if (stream_error) { 325 if (stream_error) {
514 const buzz::XmlElement* other = 326 const buzz::XmlElement* other =
515 stream_error->FirstNamed(buzz::QN_XSTREAM_SEE_OTHER_HOST); 327 stream_error->FirstNamed(buzz::QN_XSTREAM_SEE_OTHER_HOST);
516 if (other) { 328 if (other) {
517 const buzz::XmlElement* text = 329 const buzz::XmlElement* text =
518 stream_error->FirstNamed(buzz::QN_XSTREAM_TEXT); 330 stream_error->FirstNamed(buzz::QN_XSTREAM_TEXT);
519 if (text) { 331 if (text) {
(...skipping 25 matching lines...) Expand all
545 DCHECK(connection_generator_.get()); 357 DCHECK(connection_generator_.get());
546 if (!connection_generator_.get()) { 358 if (!connection_generator_.get()) {
547 return; 359 return;
548 } 360 }
549 361
550 // Iterate to the next possible connection (still trying to connect). 362 // Iterate to the next possible connection (still trying to connect).
551 UseNextConnection(); 363 UseNextConnection();
552 } 364 }
553 365
554 } // namespace notifier 366 } // namespace notifier
OLDNEW
« no previous file with comments | « jingle/notifier/communicator/single_login_attempt.h ('k') | jingle/notifier/communicator/xmpp_connection_generator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698