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

Side by Side Diff: chrome/browser/sync/notifier/communicator/xmpp_connection_generator.cc

Issue 1956001: Moved XMPP notifier library from chrome/browser/sync to chrome/common.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 7 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
(Empty)
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
3 // found in the LICENSE file.
4 //
5 // XmppConnectionGenerator does the following algorithm:
6 // proxy = ResolveProxyInformation(connection_options)
7 // for server in server_list
8 // get dns_addresses for server
9 // connection_list = (dns_addresses X connection methods X proxy).shuffle()
10 // for connection in connection_list
11 // yield connection
12
13 #include "chrome/browser/sync/notifier/communicator/xmpp_connection_generator.h"
14
15 #include <vector>
16
17 #include "base/logging.h"
18 #include "chrome/browser/sync/notifier/base/async_dns_lookup.h"
19 #include "chrome/browser/sync/notifier/base/signal_thread_task.h"
20 #include "chrome/browser/sync/notifier/communicator/connection_options.h"
21 #include "chrome/browser/sync/notifier/communicator/connection_settings.h"
22 #include "chrome/browser/sync/notifier/communicator/product_info.h"
23 #include "talk/base/autodetectproxy.h"
24 #include "talk/base/httpcommon-inl.h"
25 #include "talk/base/task.h"
26 #include "talk/base/thread.h"
27 #include "talk/xmpp/prexmppauth.h"
28 #include "talk/xmpp/xmppclientsettings.h"
29 #include "talk/xmpp/xmppengine.h"
30
31 namespace notifier {
32
33 XmppConnectionGenerator::XmppConnectionGenerator(
34 talk_base::Task* parent,
35 const ConnectionOptions* options,
36 bool proxy_only,
37 const ServerInformation* server_list,
38 int server_count)
39 : settings_list_(new ConnectionSettingsList()),
40 settings_index_(0),
41 server_list_(new ServerInformation[server_count]),
42 server_count_(server_count),
43 server_index_(-1),
44 proxy_only_(proxy_only),
45 successfully_resolved_dns_(false),
46 first_dns_error_(0),
47 options_(options),
48 parent_(parent) {
49 assert(parent);
50 assert(options);
51 assert(server_count_ > 0);
52 for (int i = 0; i < server_count_; ++i) {
53 server_list_[i] = server_list[i];
54 }
55 }
56
57 XmppConnectionGenerator::~XmppConnectionGenerator() {
58 LOG(INFO) << "XmppConnectionGenerator::~XmppConnectionGenerator";
59 }
60
61 const talk_base::ProxyInfo& XmppConnectionGenerator::proxy() const {
62 assert(settings_list_.get());
63 if (settings_index_ >= settings_list_->GetCount()) {
64 return settings_list_->proxy();
65 }
66
67 ConnectionSettings* settings = settings_list_->GetSettings(settings_index_);
68 return settings->proxy();
69 }
70
71 // Starts resolving proxy information.
72 void XmppConnectionGenerator::StartGenerating() {
73 LOG(INFO) << "XmppConnectionGenerator::StartGenerating";
74
75 talk_base::AutoDetectProxy* proxy_detect =
76 new talk_base::AutoDetectProxy(GetUserAgentString());
77
78 if (options_->autodetect_proxy()) {
79 // Pretend the xmpp server is https, when detecting whether a proxy is
80 // required to connect.
81 talk_base::Url<char> host_url("/",
82 server_list_[0].server.IPAsString().c_str(),
83 server_list_[0].server.port());
84 host_url.set_secure(true);
85 proxy_detect->set_server_url(host_url.url());
86 } else if (options_->proxy_host().length()) {
87 talk_base::SocketAddress proxy(options_->proxy_host(),
88 options_->proxy_port());
89 proxy_detect->set_proxy(proxy);
90 }
91 proxy_detect->set_auth_info(options_->use_proxy_auth(),
92 options_->auth_user(),
93 talk_base::CryptString(options_->auth_pass()));
94
95 SignalThreadTask<talk_base::AutoDetectProxy>* wrapper_task =
96 new SignalThreadTask<talk_base::AutoDetectProxy>(parent_, &proxy_detect);
97 wrapper_task->SignalWorkDone.connect(
98 this,
99 &XmppConnectionGenerator::OnProxyDetect);
100 wrapper_task->Start();
101 }
102
103 void XmppConnectionGenerator::OnProxyDetect(
104 talk_base::AutoDetectProxy* proxy_detect) {
105 LOG(INFO) << "XmppConnectionGenerator::OnProxyDetect";
106
107 ASSERT(settings_list_.get());
108 ASSERT(proxy_detect);
109 settings_list_->SetProxy(proxy_detect->proxy());
110
111 // Start iterating through the connections (which are generated on demand).
112 UseNextConnection();
113 }
114
115 void XmppConnectionGenerator::UseNextConnection() {
116 // Trying to connect.
117
118 // Iterate to the next possible connection.
119 settings_index_++;
120 if (settings_index_ < settings_list_->GetCount()) {
121 // We have more connection settings in the settings_list_ to try, kick off
122 // the next one.
123 UseCurrentConnection();
124 return;
125 }
126
127 // Iterate to the next possible server.
128 server_index_++;
129 if (server_index_ < server_count_) {
130 AsyncDNSLookup* dns_lookup = new AsyncDNSLookup(
131 server_list_[server_index_].server);
132 SignalThreadTask<AsyncDNSLookup>* wrapper_task =
133 new SignalThreadTask<AsyncDNSLookup>(parent_, &dns_lookup);
134 wrapper_task->SignalWorkDone.connect(
135 this,
136 &XmppConnectionGenerator::OnServerDNSResolved);
137 wrapper_task->Start();
138 return;
139 }
140
141 // All out of possibilities.
142 HandleExhaustedConnections();
143 }
144
145 void XmppConnectionGenerator::OnServerDNSResolved(
146 AsyncDNSLookup* dns_lookup) {
147 LOG(INFO) << "XmppConnectionGenerator::OnServerDNSResolved";
148
149 // Print logging info.
150 LOG(INFO) << " server: " <<
151 server_list_[server_index_].server.ToString() <<
152 " error: " << dns_lookup->error();
153 if (first_dns_error_ == 0 && dns_lookup->error() != 0) {
154 first_dns_error_ = dns_lookup->error();
155 }
156
157 if (!successfully_resolved_dns_ && dns_lookup->ip_list().size() > 0) {
158 successfully_resolved_dns_ = true;
159 }
160
161 for (int i = 0; i < static_cast<int>(dns_lookup->ip_list().size()); ++i) {
162 LOG(INFO)
163 << " ip " << i << " : "
164 << talk_base::SocketAddress::IPToString(dns_lookup->ip_list()[i]);
165 }
166
167 // Build the ip list.
168 assert(settings_list_.get());
169 settings_index_ = -1;
170 settings_list_->ClearPermutations();
171 settings_list_->AddPermutations(
172 server_list_[server_index_].server.IPAsString(),
173 dns_lookup->ip_list(),
174 server_list_[server_index_].server.port(),
175 server_list_[server_index_].special_port_magic,
176 proxy_only_);
177
178 UseNextConnection();
179 }
180
181 static const char* const PROTO_NAMES[cricket::PROTO_LAST + 1] = {
182 "udp", "tcp", "ssltcp"
183 };
184
185 static const char* ProtocolToString(cricket::ProtocolType proto) {
186 return PROTO_NAMES[proto];
187 }
188
189 void XmppConnectionGenerator::UseCurrentConnection() {
190 LOG(INFO) << "XmppConnectionGenerator::UseCurrentConnection";
191
192 ConnectionSettings* settings = settings_list_->GetSettings(settings_index_);
193 LOG(INFO) << "*** Attempting "
194 << ProtocolToString(settings->protocol()) << " connection to "
195 << settings->server().IPAsString() << ":"
196 << settings->server().port()
197 << " (via " << ProxyToString(settings->proxy().type)
198 << " proxy @ " << settings->proxy().address.IPAsString() << ":"
199 << settings->proxy().address.port() << ")";
200
201 SignalNewSettings(*settings);
202 }
203
204 void XmppConnectionGenerator::HandleExhaustedConnections() {
205 LOG(INFO) << "(" << buzz::XmppEngine::ERROR_SOCKET
206 << ", " << first_dns_error_ << ")";
207 SignalExhaustedSettings(successfully_resolved_dns_, first_dns_error_);
208 }
209
210 } // namespace notifier
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698