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

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

Issue 194065: Initial commit of sync engine code to browser/sync.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Fixes to gtest include path, reverted syncapi. Created 11 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
Property Changes:
Added: svn:eol-style
+ LF
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 "chrome/browser/sync/notifier/base/async_dns_lookup.h"
18 #include "chrome/browser/sync/notifier/base/signal_thread_task.h"
19 #include "chrome/browser/sync/notifier/communicator/connection_options.h"
20 #include "chrome/browser/sync/notifier/communicator/connection_settings.h"
21 #include "chrome/browser/sync/notifier/communicator/product_info.h"
22 #include "talk/base/autodetectproxy.h"
23 #include "talk/base/httpcommon.h"
24 #include "talk/base/logging.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(LS_VERBOSE) << "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(LS_VERBOSE) << "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(LS_VERBOSE) << "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
112 // are generated on demand).
113 UseNextConnection();
114 }
115
116 void XmppConnectionGenerator::UseNextConnection() {
117 // Trying to connect
118
119 // Iterate to the next possible connection
120 settings_index_++;
121 if (settings_index_ < settings_list_->GetCount()) {
122 // We have more connection settings in the settings_list_ to try, kick
123 // off the next one.
124 UseCurrentConnection();
125 return;
126 }
127
128 // Iterate to the next possible server
129 server_index_++;
130 if (server_index_ < server_count_) {
131 AsyncDNSLookup* dns_lookup = new AsyncDNSLookup(
132 server_list_[server_index_].server);
133 SignalThreadTask<AsyncDNSLookup>* wrapper_task =
134 new SignalThreadTask<AsyncDNSLookup>(parent_, &dns_lookup);
135 wrapper_task->SignalWorkDone.connect(
136 this,
137 &XmppConnectionGenerator::OnServerDNSResolved);
138 wrapper_task->Start();
139 return;
140 }
141
142 // All out of possibilities
143 HandleExhaustedConnections();
144 }
145
146 void XmppConnectionGenerator::OnServerDNSResolved(
147 AsyncDNSLookup* dns_lookup) {
148 LOG(LS_VERBOSE) << "XmppConnectionGenerator::OnServerDNSResolved";
149
150 // Print logging info
151 LOG(LS_VERBOSE) << " server: " <<
152 server_list_[server_index_].server.ToString() <<
153 " error: " << dns_lookup->error();
154 if (first_dns_error_ == 0 && dns_lookup->error() != 0) {
155 first_dns_error_ = dns_lookup->error();
156 }
157
158 if (!successfully_resolved_dns_ && dns_lookup->ip_list().size() > 0) {
159 successfully_resolved_dns_ = true;
160 }
161
162 for (int i = 0; i < static_cast<int>(dns_lookup->ip_list().size()); ++i) {
163 LOG(LS_VERBOSE)
164 << " ip " << i << " : "
165 << talk_base::SocketAddress::IPToString(dns_lookup->ip_list()[i]);
166 }
167
168 // Build the ip list
169 assert(settings_list_.get());
170 settings_index_ = -1;
171 settings_list_->ClearPermutations();
172 settings_list_->AddPermutations(
173 server_list_[server_index_].server.IPAsString(),
174 dns_lookup->ip_list(),
175 server_list_[server_index_].server.port(),
176 server_list_[server_index_].special_port_magic,
177 proxy_only_);
178
179 UseNextConnection();
180 }
181
182 static const char * const PROTO_NAMES[cricket::PROTO_LAST+1] = {
183 "udp", "tcp", "ssltcp"
184 };
185
186 static const char* ProtocolToString(cricket::ProtocolType proto) {
187 return PROTO_NAMES[proto];
188 }
189
190 void XmppConnectionGenerator::UseCurrentConnection() {
191 LOG(LS_VERBOSE) << "XmppConnectionGenerator::UseCurrentConnection";
192
193 ConnectionSettings* settings = settings_list_->GetSettings(settings_index_);
194 LOG(LS_INFO) << "*** Attempting "
195 << ProtocolToString(settings->protocol()) << " connection to "
196 << settings->server().IPAsString() << ":"
197 << settings->server().port()
198 << " (via " << ProxyToString(settings->proxy().type)
199 << " proxy @ " << settings->proxy().address.IPAsString() << ":"
200 << settings->proxy().address.port() << ")";
201
202 SignalNewSettings(*settings);
203 }
204
205 void XmppConnectionGenerator::HandleExhaustedConnections() {
206 LOG_F(LS_VERBOSE) << "(" << buzz::XmppEngine::ERROR_SOCKET
207 << ", " << first_dns_error_ << ")";
208 SignalExhaustedSettings(successfully_resolved_dns_, first_dns_error_);
209 }
210 } // namespace notifier
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698