summaryrefslogtreecommitdiffstats
path: root/jingle/notifier/communicator/connection_settings.cc
diff options
context:
space:
mode:
Diffstat (limited to 'jingle/notifier/communicator/connection_settings.cc')
-rw-r--r--jingle/notifier/communicator/connection_settings.cc128
1 files changed, 128 insertions, 0 deletions
diff --git a/jingle/notifier/communicator/connection_settings.cc b/jingle/notifier/communicator/connection_settings.cc
new file mode 100644
index 0000000..1347e46
--- /dev/null
+++ b/jingle/notifier/communicator/connection_settings.cc
@@ -0,0 +1,128 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <algorithm>
+#include <deque>
+#include <string>
+#include <vector>
+
+#include "base/logging.h"
+#include "jingle/notifier/communicator/connection_settings.h"
+#include "talk/base/helpers.h"
+#include "talk/xmpp/xmppclientsettings.h"
+
+namespace notifier {
+
+class RandomGenerator {
+ public:
+ int operator()(int ceiling) {
+ return static_cast<int>(talk_base::CreateRandomId() % ceiling);
+ }
+};
+
+void ConnectionSettings::FillXmppClientSettings(
+ buzz::XmppClientSettings* xcs) const {
+ DCHECK(xcs);
+ xcs->set_protocol(protocol_);
+ xcs->set_server(server_);
+ xcs->set_proxy(proxy_.type);
+ if (proxy_.type != talk_base::PROXY_NONE) {
+ xcs->set_proxy_host(proxy_.address.IPAsString());
+ xcs->set_proxy_port(proxy_.address.port());
+ }
+ if ((proxy_.type != talk_base::PROXY_NONE) && !proxy_.username.empty()) {
+ xcs->set_use_proxy_auth(true);
+ xcs->set_proxy_user(proxy_.username);
+ xcs->set_proxy_pass(proxy_.password);
+ } else {
+ xcs->set_use_proxy_auth(false);
+ }
+}
+
+void ConnectionSettingsList::AddPermutations(const std::string& hostname,
+ const std::vector<uint32>& iplist,
+ int16 port,
+ bool special_port_magic,
+ bool proxy_only) {
+ // randomize the list. This ensures the iplist isn't always
+ // evaluated in the order returned by DNS
+ std::vector<uint32> iplist_random = iplist;
+ RandomGenerator rg;
+ std::random_shuffle(iplist_random.begin(), iplist_random.end(), rg);
+
+ // Put generated addresses in a new deque, then append on the list_, since
+ // there are order dependencies and AddPermutations() may be called more
+ // than once.
+ std::deque<ConnectionSettings> list_temp;
+
+ // Permute addresses for this server. In some cases we haven't resolved the
+ // to ip addresses.
+ talk_base::SocketAddress server(hostname, port);
+ if (iplist_random.empty()) {
+ // We couldn't pre-resolve the hostname, so let's hope it will resolve
+ // further down the pipeline (by a proxy, for example).
+ PermuteForAddress(server, special_port_magic, proxy_only, &list_temp);
+ } else {
+ // Generate a set of possibilities for each server address.
+ // Don't do permute duplicates.
+ for (size_t index = 0; index < iplist_random.size(); ++index) {
+ if (std::find(iplist_seen_.begin(), iplist_seen_.end(),
+ iplist_random[index]) != iplist_seen_.end()) {
+ continue;
+ }
+ iplist_seen_.push_back(iplist_random[index]);
+ server.SetResolvedIP(iplist_random[index]);
+ PermuteForAddress(server, special_port_magic, proxy_only, &list_temp);
+ }
+ }
+
+ // Add this list to the instance list
+ while (list_temp.size() != 0) {
+ list_.push_back(list_temp[0]);
+ list_temp.pop_front();
+ }
+}
+
+
+void ConnectionSettingsList::PermuteForAddress(
+ const talk_base::SocketAddress& server,
+ bool special_port_magic,
+ bool proxy_only,
+ std::deque<ConnectionSettings>* list_temp) {
+ DCHECK(list_temp);
+ *(template_.mutable_server()) = server;
+
+ // Use all of the original settings
+ list_temp->push_back(template_);
+
+ // Try alternate port
+ if (special_port_magic) {
+ ConnectionSettings settings(template_);
+ settings.set_protocol(cricket::PROTO_SSLTCP);
+ settings.mutable_server()->SetPort(443);
+ // HTTPS proxies usually require port 443, so try it first
+ if ((template_.proxy().type == talk_base::PROXY_HTTPS) ||
+ (template_.proxy().type == talk_base::PROXY_UNKNOWN)) {
+ list_temp->push_front(settings);
+ } else {
+ list_temp->push_back(settings);
+ }
+ }
+
+ if (!proxy_only) {
+ // Try without the proxy
+ if (template_.proxy().type != talk_base::PROXY_NONE) {
+ ConnectionSettings settings(template_);
+ settings.mutable_proxy()->type = talk_base::PROXY_NONE;
+ list_temp->push_back(settings);
+
+ if (special_port_magic) {
+ settings.set_protocol(cricket::PROTO_SSLTCP);
+ settings.mutable_server()->SetPort(443);
+ list_temp->push_back(settings);
+ }
+ }
+ }
+}
+} // namespace notifier