1269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org/*
2269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
3269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org *
4269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org *  Use of this source code is governed by a BSD-style license
5269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org *  that can be found in the LICENSE file in the root of the source
6269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org *  tree. An additional intellectual property rights grant can be found
7269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org *  in the file PATENTS.  All contributing project authors may
8269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org */
10269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
11269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/p2p/client/httpportallocator.h"
12269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
13269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include <algorithm>
14269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include <map>
15269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
16269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/base/common.h"
17269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/base/helpers.h"
18d415629de78b84bf539fda7f634996e159b0dcaaPeter Thatcher#include "webrtc/base/httpcommon.h"
19269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/base/logging.h"
20269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/base/nethelpers.h"
21269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/base/signalthread.h"
22269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/base/stringencode.h"
23269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
24269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgnamespace {
25269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
26269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// Helper routine to remove whitespace from the ends of a string.
27269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgvoid Trim(std::string& str) {
28269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  size_t first = str.find_first_not_of(" \t\r\n");
29269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  if (first == std::string::npos) {
30269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    str.clear();
31269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    return;
32269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
33269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
34269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT(str.find_last_not_of(" \t\r\n") != std::string::npos);
35269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
36269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
37269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// Parses the lines in the result of the HTTP request that are of the form
38269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// 'a=b' and returns them in a map.
39269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgtypedef std::map<std::string, std::string> StringMap;
40269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgvoid ParseMap(const std::string& string, StringMap& map) {
41269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  size_t start_of_line = 0;
42269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  size_t end_of_line = 0;
43269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
44269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  for (;;) {  // for each line
45269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    start_of_line = string.find_first_not_of("\r\n", end_of_line);
46269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    if (start_of_line == std::string::npos)
47269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      break;
48269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
49269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    end_of_line = string.find_first_of("\r\n", start_of_line);
50269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    if (end_of_line == std::string::npos) {
51269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      end_of_line = string.length();
52269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    }
53269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
54269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    size_t equals = string.find('=', start_of_line);
55269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    if ((equals >= end_of_line) || (equals == std::string::npos))
56269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      continue;
57269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
58269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    std::string key(string, start_of_line, equals - start_of_line);
59269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    std::string value(string, equals + 1, end_of_line - equals - 1);
60269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
61269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    Trim(key);
62269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    Trim(value);
63269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
64269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    if ((key.size() > 0) && (value.size() > 0))
65269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      map[key] = value;
66269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
67269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
68269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
69269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}  // namespace
70269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
71269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgnamespace cricket {
72269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
73269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// HttpPortAllocatorBase
74269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
75269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgconst int HttpPortAllocatorBase::kNumRetries = 5;
76269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
77269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgconst char HttpPortAllocatorBase::kCreateSessionURL[] = "/create_session";
78269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
79269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgHttpPortAllocatorBase::HttpPortAllocatorBase(
80269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    rtc::NetworkManager* network_manager,
81269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    rtc::PacketSocketFactory* socket_factory,
82269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    const std::string &user_agent)
83269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    : BasicPortAllocator(network_manager, socket_factory), agent_(user_agent) {
84269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  relay_hosts_.push_back("relay.google.com");
85269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  stun_hosts_.push_back(
86269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      rtc::SocketAddress("stun.l.google.com", 19302));
87269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
88269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
89269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgHttpPortAllocatorBase::HttpPortAllocatorBase(
90269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    rtc::NetworkManager* network_manager,
91269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    const std::string &user_agent)
92269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    : BasicPortAllocator(network_manager), agent_(user_agent) {
93269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  relay_hosts_.push_back("relay.google.com");
94269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  stun_hosts_.push_back(
95269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      rtc::SocketAddress("stun.l.google.com", 19302));
96269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
97269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
98269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgHttpPortAllocatorBase::~HttpPortAllocatorBase() {
99269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
100269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
101269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// HttpPortAllocatorSessionBase
102269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
103269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgHttpPortAllocatorSessionBase::HttpPortAllocatorSessionBase(
104269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    HttpPortAllocatorBase* allocator,
105269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    const std::string& content_name,
106269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    int component,
107269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    const std::string& ice_ufrag,
108269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    const std::string& ice_pwd,
109269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    const std::vector<rtc::SocketAddress>& stun_hosts,
110269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    const std::vector<std::string>& relay_hosts,
111269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    const std::string& relay_token,
112269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    const std::string& user_agent)
113269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    : BasicPortAllocatorSession(allocator, content_name, component,
114269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                ice_ufrag, ice_pwd),
115269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      relay_hosts_(relay_hosts), stun_hosts_(stun_hosts),
116269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      relay_token_(relay_token), agent_(user_agent), attempts_(0) {
117269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
118269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
119269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgHttpPortAllocatorSessionBase::~HttpPortAllocatorSessionBase() {}
120269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
121269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgvoid HttpPortAllocatorSessionBase::GetPortConfigurations() {
122269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Creating relay sessions can take time and is done asynchronously.
123269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Creating stun sessions could also take time and could be done aysnc also,
124269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // but for now is done here and added to the initial config.  Note any later
125269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // configs will have unresolved stun ips and will be discarded by the
126269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // AllocationSequence.
127269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ServerAddresses hosts;
128269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  for (std::vector<rtc::SocketAddress>::iterator it = stun_hosts_.begin();
129269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      it != stun_hosts_.end(); ++it) {
130269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    hosts.insert(*it);
131269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
132269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
133269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  PortConfiguration* config = new PortConfiguration(hosts,
134269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                                    username(),
135269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                                    password());
136269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ConfigReady(config);
137269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TryCreateRelaySession();
138269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
139269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
140269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgvoid HttpPortAllocatorSessionBase::TryCreateRelaySession() {
141269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  if (allocator()->flags() & PORTALLOCATOR_DISABLE_RELAY) {
142269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    LOG(LS_VERBOSE) << "HttpPortAllocator: Relay ports disabled, skipping.";
143269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    return;
144269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
145269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
146d415629de78b84bf539fda7f634996e159b0dcaaPeter Thatcher  if (attempts_ == HttpPortAllocatorBase::kNumRetries) {
147269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    LOG(LS_ERROR) << "HttpPortAllocator: maximum number of requests reached; "
148269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                  << "giving up on relay.";
149269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    return;
150269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
151269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
152269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  if (relay_hosts_.size() == 0) {
153269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    LOG(LS_ERROR) << "HttpPortAllocator: no relay hosts configured.";
154269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    return;
155269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
156269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
157269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Choose the next host to try.
158269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  std::string host = relay_hosts_[attempts_ % relay_hosts_.size()];
159269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  attempts_++;
160269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  LOG(LS_INFO) << "HTTPPortAllocator: sending to relay host " << host;
161269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  if (relay_token_.empty()) {
162269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    LOG(LS_WARNING) << "No relay auth token found.";
163269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
164269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
165269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  SendSessionRequest(host, rtc::HTTP_SECURE_PORT);
166269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
167269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
168269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgstd::string HttpPortAllocatorSessionBase::GetSessionRequestUrl() {
169d415629de78b84bf539fda7f634996e159b0dcaaPeter Thatcher  std::string url = std::string(HttpPortAllocatorBase::kCreateSessionURL);
1702159b89fa2cb55beeef38f72bd45e217f3d33d4ePeter Thatcher  ASSERT(!username().empty());
1712159b89fa2cb55beeef38f72bd45e217f3d33d4ePeter Thatcher  ASSERT(!password().empty());
1722159b89fa2cb55beeef38f72bd45e217f3d33d4ePeter Thatcher  url = url + "?username=" + rtc::s_url_encode(username()) +
1732159b89fa2cb55beeef38f72bd45e217f3d33d4ePeter Thatcher      "&password=" + rtc::s_url_encode(password());
174269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  return url;
175269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
176269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
177269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgvoid HttpPortAllocatorSessionBase::ReceiveSessionResponse(
178269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    const std::string& response) {
179269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
180269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  StringMap map;
181269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ParseMap(response, map);
182269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
183269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  if (!username().empty() && map["username"] != username()) {
184269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    LOG(LS_WARNING) << "Received unexpected username value from relay server.";
185269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
186269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  if (!password().empty() && map["password"] != password()) {
187269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    LOG(LS_WARNING) << "Received unexpected password value from relay server.";
188269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
189269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
190269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  std::string relay_ip = map["relay.ip"];
191269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  std::string relay_udp_port = map["relay.udp_port"];
192269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  std::string relay_tcp_port = map["relay.tcp_port"];
193269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  std::string relay_ssltcp_port = map["relay.ssltcp_port"];
194269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
195269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ServerAddresses hosts;
196269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  for (std::vector<rtc::SocketAddress>::iterator it = stun_hosts_.begin();
197269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      it != stun_hosts_.end(); ++it) {
198269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    hosts.insert(*it);
199269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
200269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
201269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  PortConfiguration* config = new PortConfiguration(hosts,
202269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                                    map["username"],
203269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                                    map["password"]);
204269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
205269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  RelayServerConfig relay_config(RELAY_GTURN);
206269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  if (!relay_udp_port.empty()) {
207269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    rtc::SocketAddress address(relay_ip, atoi(relay_udp_port.c_str()));
208269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    relay_config.ports.push_back(ProtocolAddress(address, PROTO_UDP));
209269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
210269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  if (!relay_tcp_port.empty()) {
211269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    rtc::SocketAddress address(relay_ip, atoi(relay_tcp_port.c_str()));
212269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    relay_config.ports.push_back(ProtocolAddress(address, PROTO_TCP));
213269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
214269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  if (!relay_ssltcp_port.empty()) {
215269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    rtc::SocketAddress address(relay_ip, atoi(relay_ssltcp_port.c_str()));
216269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    relay_config.ports.push_back(ProtocolAddress(address, PROTO_SSLTCP));
217269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
218269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  config->AddRelay(relay_config);
219269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ConfigReady(config);
220269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
221269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
222269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}  // namespace cricket
223