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