OLD | NEW |
| (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 #include <algorithm> | |
6 #include <deque> | |
7 #include <string> | |
8 #include <vector> | |
9 | |
10 #include "chrome/browser/sync/notifier/communicator/connection_settings.h" | |
11 #include "talk/base/helpers.h" | |
12 #include "talk/xmpp/xmppclientsettings.h" | |
13 | |
14 namespace notifier { | |
15 | |
16 class RandomGenerator { | |
17 public: | |
18 int operator()(int ceiling) { | |
19 return static_cast<int>(cricket::CreateRandomId() % ceiling); | |
20 } | |
21 }; | |
22 | |
23 void ConnectionSettings::FillXmppClientSettings( | |
24 buzz::XmppClientSettings* xcs) const { | |
25 assert(xcs); | |
26 xcs->set_protocol(protocol_); | |
27 xcs->set_server(server_); | |
28 xcs->set_proxy(proxy_.type); | |
29 if (proxy_.type != talk_base::PROXY_NONE) { | |
30 xcs->set_proxy_host(proxy_.address.IPAsString()); | |
31 xcs->set_proxy_port(proxy_.address.port()); | |
32 } | |
33 if ((proxy_.type != talk_base::PROXY_NONE) && !proxy_.username.empty()) { | |
34 xcs->set_use_proxy_auth(true); | |
35 xcs->set_proxy_user(proxy_.username); | |
36 xcs->set_proxy_pass(proxy_.password); | |
37 } else { | |
38 xcs->set_use_proxy_auth(false); | |
39 } | |
40 } | |
41 | |
42 void ConnectionSettingsList::AddPermutations(const std::string& hostname, | |
43 const std::vector<uint32>& iplist, | |
44 int16 port, | |
45 bool special_port_magic, | |
46 bool proxy_only) { | |
47 // randomize the list. This ensures the iplist isn't always | |
48 // evaluated in the order returned by DNS | |
49 std::vector<uint32> iplist_random = iplist; | |
50 RandomGenerator rg; | |
51 std::random_shuffle(iplist_random.begin(), iplist_random.end(), rg); | |
52 | |
53 // Put generated addresses in a new deque, then append on the list_, since | |
54 // there are order dependencies and AddPermutations() may be called more | |
55 // than once. | |
56 std::deque<ConnectionSettings> list_temp; | |
57 | |
58 // Permute addresses for this server. In some cases we haven't resolved the | |
59 // to ip addresses. | |
60 talk_base::SocketAddress server(hostname, port, false); | |
61 if (iplist_random.empty()) { | |
62 // We couldn't pre-resolve the hostname, so let's hope it will resolve | |
63 // further down the pipeline (by a proxy, for example). | |
64 PermuteForAddress(server, special_port_magic, proxy_only, &list_temp); | |
65 } else { | |
66 // Generate a set of possibilities for each server address. | |
67 // Don't do permute duplicates. | |
68 for (size_t index = 0; index < iplist_random.size(); ++index) { | |
69 if (std::find(iplist_seen_.begin(), iplist_seen_.end(), | |
70 iplist_random[index]) != iplist_seen_.end()) { | |
71 continue; | |
72 } | |
73 iplist_seen_.push_back(iplist_random[index]); | |
74 server.SetResolvedIP(iplist_random[index]); | |
75 PermuteForAddress(server, special_port_magic, proxy_only, &list_temp); | |
76 } | |
77 } | |
78 | |
79 // Add this list to the instance list | |
80 while (list_temp.size() != 0) { | |
81 list_.push_back(list_temp[0]); | |
82 list_temp.pop_front(); | |
83 } | |
84 } | |
85 | |
86 | |
87 void ConnectionSettingsList::PermuteForAddress( | |
88 const talk_base::SocketAddress& server, | |
89 bool special_port_magic, | |
90 bool proxy_only, | |
91 std::deque<ConnectionSettings>* list_temp) { | |
92 assert(list_temp); | |
93 *(template_.mutable_server()) = server; | |
94 | |
95 // Use all of the original settings | |
96 list_temp->push_back(template_); | |
97 | |
98 // Try alternate port | |
99 if (special_port_magic) { | |
100 ConnectionSettings settings(template_); | |
101 settings.set_protocol(cricket::PROTO_SSLTCP); | |
102 settings.mutable_server()->SetPort(443); | |
103 // HTTPS proxies usually require port 443, so try it first | |
104 if ((template_.proxy().type == talk_base::PROXY_HTTPS) || | |
105 (template_.proxy().type == talk_base::PROXY_UNKNOWN)) { | |
106 list_temp->push_front(settings); | |
107 } else { | |
108 list_temp->push_back(settings); | |
109 } | |
110 } | |
111 | |
112 if (!proxy_only) { | |
113 // Try without the proxy | |
114 if (template_.proxy().type != talk_base::PROXY_NONE) { | |
115 ConnectionSettings settings(template_); | |
116 settings.mutable_proxy()->type = talk_base::PROXY_NONE; | |
117 list_temp->push_back(settings); | |
118 | |
119 if (special_port_magic) { | |
120 settings.set_protocol(cricket::PROTO_SSLTCP); | |
121 settings.mutable_server()->SetPort(443); | |
122 list_temp->push_back(settings); | |
123 } | |
124 } | |
125 } | |
126 } | |
127 } // namespace notifier | |
OLD | NEW |